(git:07a6c39)
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-2026 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 casino_utils, ONLY: write_casino
26 USE cell_types, ONLY: cell_type
31 USE cp_dbcsr_api, ONLY: dbcsr_add,&
37 USE cp_ddapc_util, ONLY: get_ddapc
42 USE cp_fm_types, ONLY: cp_fm_create,&
53 cp_p_file,&
64 USE dct, ONLY: pw_shrink
65 USE ed_analysis, ONLY: edmf_analysis
66 USE eeq_method, ONLY: eeq_print
69 USE hfx_ri, ONLY: print_ri_hfx
80 USE iao_types, ONLY: iao_env_type,&
82 USE input_constants, ONLY: &
94 USE kinds, ONLY: default_path_length,&
96 dp
98 USE kpoint_types, ONLY: kpoint_type
101 USE mathconstants, ONLY: pi
107 USE mulliken, ONLY: mulliken_charges
108 USE orbital_pointers, ONLY: indso
111 USE physcon, ONLY: a_bohr,&
112 angstrom,&
113 debye,&
114 evolt
118 USE ps_implicit_types, ONLY: mixed_bc,&
120 neumann_bc,&
122 USE pw_env_types, ONLY: pw_env_get,&
124 USE pw_grids, ONLY: get_pw_grid_info
125 USE pw_methods, ONLY: pw_axpy,&
126 pw_copy,&
127 pw_derive,&
129 pw_scale,&
131 pw_zero
135 USE pw_pool_types, ONLY: pw_pool_p_type,&
137 USE pw_types, ONLY: pw_c1d_gs_type,&
139 USE qs_chargemol, ONLY: write_wfx
145 USE qs_dos, ONLY: calculate_dos,&
149 USE qs_elf_methods, ONLY: qs_elf_calc
155 USE qs_epr_hyp, ONLY: qs_epr_hyp_calc
158 USE qs_kind_types, ONLY: get_qs_kind,&
164 USE qs_loc_dipole, ONLY: loc_dipole
180 USE qs_mo_types, ONLY: get_mo_set,&
195 USE qs_resp, ONLY: resp_fit
196 USE qs_rho0_types, ONLY: get_rho0_mpole,&
201 USE qs_rho_types, ONLY: qs_rho_get,&
208 USE qs_scf_types, ONLY: ot_method_nr,&
210 USE qs_scf_wfn_mix, ONLY: wfn_mix
211 USE qs_subsys_types, ONLY: qs_subsys_get,&
216 USE stm_images, ONLY: th_stm_image
218 USE trexio_utils, ONLY: write_trexio
219 USE virial_types, ONLY: virial_type
222#include "./base/base_uses.f90"
223
224 IMPLICIT NONE
225 PRIVATE
226
227 ! Global parameters
228 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_scf_post_gpw'
229 PUBLIC :: make_lumo_gpw, &
234
235 CHARACTER(len=*), PARAMETER :: &
236 str_mo_cubes = "PRINT%MO_CUBES", &
237 str_mo_openpmd = "PRINT%MO_OPENPMD", &
238 str_elf_cubes = "PRINT%ELF_CUBE", &
239 str_elf_openpmd = "PRINT%ELF_OPENPMD", &
240 str_e_density_cubes = "PRINT%E_DENSITY_CUBE", &
241 str_e_density_openpmd = "PRINT%E_DENSITY_OPENPMD"
242
243 INTEGER, PARAMETER :: grid_output_cubes = 1, grid_output_openpmd = 2
244
245 REAL(kind=dp), DIMENSION(7), PARAMETER :: openpmd_unit_dimension_density = &
246 [-3, 0, 0, 0, 0, 0, 0]
247 REAL(kind=dp), DIMENSION(7), PARAMETER :: openpmd_unit_dimension_dimensionless = &
248 [0, 0, 0, 0, 0, 0, 0]
249 REAL(kind=dp), DIMENSION(7), PARAMETER :: openpmd_unit_dimension_wavefunction = &
250 [-1.5_dp, 0.0_dp, 0.0_dp, 0.0_dp, 0.0_dp, 0.0_dp, 0.0_dp]
251 REAL(kind=dp), PARAMETER :: openpmd_unit_si_density = a_bohr**(-3)
252 REAL(kind=dp), PARAMETER :: openpmd_unit_si_dimensionless = 1.0_dp
253 REAL(kind=dp), PARAMETER :: openpmd_unit_si_wavefunction = a_bohr**(-1.5_dp)
254
255 ! Generic information on whether a certain output section has been activated
256 ! or not, and on whether it has been activated in the Cube or openPMD variant.
257 ! Create with function cube_or_openpmd(), see there for further details.
258 TYPE cp_section_key
259 CHARACTER(len=default_string_length) :: relative_section_key = "" ! e.g. PRINT%MO_CUBES
260 CHARACTER(len=default_string_length) :: absolute_section_key = "" ! e.g. DFT%PRINT%MO_CUBES
261 CHARACTER(len=7) :: format_name = "" ! 'openPMD' or 'Cube', for logging
262 INTEGER :: grid_output = -1 ! either 1 for grid_output_cubes or 2 for grid_output_openpmd
263 LOGICAL :: do_output = .false.
264 CONTAINS
265 ! Open a file as either Cube or openPMD
266 PROCEDURE, PUBLIC :: print_key_unit_nr => cp_forward_print_key_unit_nr
267 ! Write either to the Cube or openPMD file
268 PROCEDURE, PUBLIC :: write_pw => cp_forward_write_pw
269 ! Close either the Cube or openPMD file
270 PROCEDURE, PUBLIC :: print_key_finished_output => cp_forward_print_key_finished_output
271 ! Helpers
272 PROCEDURE, PUBLIC :: do_openpmd => cp_section_key_do_openpmd
273 PROCEDURE, PUBLIC :: do_cubes => cp_section_key_do_cubes
274 PROCEDURE, PUBLIC :: concat_to_relative => cp_section_key_concat_to_relative
275 PROCEDURE, PUBLIC :: concat_to_absolute => cp_section_key_concat_to_absolute
276 END TYPE cp_section_key
277
278CONTAINS
279
280! **************************************************************************************************
281!> \brief Append `extend_by` to the absolute path of the base section.
282!> \param self ...
283!> \param extend_by ...
284!> \return ...
285! **************************************************************************************************
286 FUNCTION cp_section_key_concat_to_absolute(self, extend_by) RESULT(res)
287 CLASS(cp_section_key), INTENT(IN) :: self
288 CHARACTER(*), INTENT(IN) :: extend_by
289 CHARACTER(len=default_string_length) :: res
290
291 IF (len(trim(extend_by)) > 0 .AND. extend_by(1:1) == "%") THEN
292 res = trim(self%absolute_section_key)//trim(extend_by)
293 ELSE
294 res = trim(self%absolute_section_key)//"%"//trim(extend_by)
295 END IF
297
298! **************************************************************************************************
299!> \brief Append `extend_by` to the relative path (e.g. without DFT%) of the base section.
300!> \param self ...
301!> \param extend_by ...
302!> \return ...
303! **************************************************************************************************
304 FUNCTION cp_section_key_concat_to_relative(self, extend_by) RESULT(res)
305 CLASS(cp_section_key), INTENT(IN) :: self
306 CHARACTER(*), INTENT(IN) :: extend_by
307 CHARACTER(len=default_string_length) :: res
308
309 IF (len(trim(extend_by)) > 0 .AND. extend_by(1:1) == "%") THEN
310 res = trim(self%relative_section_key)//trim(extend_by)
311 ELSE
312 res = trim(self%relative_section_key)//"%"//trim(extend_by)
313 END IF
314 END FUNCTION cp_section_key_concat_to_relative
315
316! **************************************************************************************************
317!> \brief Is Cube output active for the current base section?
318!> \param self ...
319!> \return ...
320! **************************************************************************************************
321 FUNCTION cp_section_key_do_cubes(self) RESULT(res)
322 CLASS(cp_section_key) :: self
323 LOGICAL :: res
324
325 res = self%do_output .AND. self%grid_output == grid_output_cubes
326 END FUNCTION cp_section_key_do_cubes
327
328! **************************************************************************************************
329!> \brief Is openPMD output active for the current base section?
330!> \param self ...
331!> \return ...
332! **************************************************************************************************
333 FUNCTION cp_section_key_do_openpmd(self) RESULT(res)
334 CLASS(cp_section_key) :: self
335 LOGICAL :: res
336
337 res = self%do_output .AND. self%grid_output == grid_output_openpmd
338 END FUNCTION cp_section_key_do_openpmd
339
340! **************************************************************************************************
341!> \brief Forwards to either `cp_print_key_unit_nr` or `cp_openpmd_print_key_unit_nr`,
342!> depending on the configuration of the current base section.
343!> Opens either a Cube or openPMD output file
344!> \param self ...
345!> \param logger ...
346!> \param basis_section ...
347!> \param print_key_path ...
348!> \param extension ...
349!> \param middle_name ...
350!> \param local ...
351!> \param log_filename ...
352!> \param ignore_should_output ...
353!> \param file_form ...
354!> \param file_position ...
355!> \param file_action ...
356!> \param file_status ...
357!> \param do_backup ...
358!> \param on_file ...
359!> \param is_new_file ...
360!> \param mpi_io ...
361!> \param fout ...
362!> \param openpmd_basename ...
363!> \param openpmd_unit_dimension ...
364!> \param openpmd_unit_si ...
365!> \param sim_time ...
366!> \return ...
367! **************************************************************************************************
368 FUNCTION cp_forward_print_key_unit_nr( &
369 self, &
370 logger, &
371 basis_section, &
372 print_key_path, &
373 extension, &
374 middle_name, &
375 local, &
376 log_filename, &
377 ignore_should_output, &
378 file_form, &
379 file_position, &
380 file_action, &
381 file_status, &
382 do_backup, &
383 on_file, &
384 is_new_file, &
385 mpi_io, &
386 fout, &
387 openpmd_basename, &
388 openpmd_unit_dimension, &
389 openpmd_unit_si, &
390 sim_time) RESULT(res)
391
392 CLASS(cp_section_key), INTENT(IN) :: self
393 TYPE(cp_logger_type), POINTER :: logger
394 TYPE(section_vals_type), INTENT(IN) :: basis_section
395 CHARACTER(len=*), INTENT(IN), OPTIONAL :: print_key_path
396 CHARACTER(len=*), INTENT(IN) :: extension
397 CHARACTER(len=*), INTENT(IN), OPTIONAL :: middle_name
398 LOGICAL, INTENT(IN), OPTIONAL :: local, log_filename, ignore_should_output
399 CHARACTER(len=*), INTENT(IN), OPTIONAL :: file_form, file_position, file_action, &
400 file_status
401 LOGICAL, INTENT(IN), OPTIONAL :: do_backup, on_file
402 LOGICAL, INTENT(OUT), OPTIONAL :: is_new_file
403 LOGICAL, INTENT(INOUT), OPTIONAL :: mpi_io
404 CHARACTER(len=default_path_length), INTENT(OUT), &
405 OPTIONAL :: fout
406 CHARACTER(len=*), INTENT(IN), OPTIONAL :: openpmd_basename
407 REAL(kind=dp), DIMENSION(7), OPTIONAL, INTENT(IN) :: openpmd_unit_dimension
408 REAL(kind=dp), OPTIONAL, INTENT(IN) :: openpmd_unit_si
409 REAL(kind=dp), OPTIONAL, INTENT(IN) :: sim_time
410 INTEGER :: res
411
412 IF (self%grid_output == grid_output_cubes) THEN
413 res = cp_print_key_unit_nr( &
414 logger, basis_section, print_key_path, extension=extension, &
415 middle_name=middle_name, local=local, log_filename=log_filename, &
416 ignore_should_output=ignore_should_output, file_form=file_form, &
417 file_position=file_position, file_action=file_action, &
418 file_status=file_status, do_backup=do_backup, on_file=on_file, &
419 is_new_file=is_new_file, mpi_io=mpi_io, fout=fout)
420 ELSE
422 logger, &
423 basis_section, &
424 print_key_path, &
425 middle_name=middle_name, &
426 ignore_should_output=ignore_should_output, &
427 mpi_io=mpi_io, &
428 fout=fout, &
429 openpmd_basename=openpmd_basename, &
430 openpmd_unit_dimension=openpmd_unit_dimension, &
431 openpmd_unit_si=openpmd_unit_si, &
432 sim_time=sim_time)
433 END IF
434 END FUNCTION cp_forward_print_key_unit_nr
435
436! **************************************************************************************************
437!> \brief Forwards to either `cp_pw_to_cube` or `cp_pw_to_openpmd`,
438!> depending on the configuration of the current base section.
439!> Writes data to either a Cube or an openPMD file.
440!> \param self ...
441!> \param pw ...
442!> \param unit_nr ...
443!> \param title ...
444!> \param particles ...
445!> \param zeff ...
446!> \param stride ...
447!> \param max_file_size_mb ...
448!> \param zero_tails ...
449!> \param silent ...
450!> \param mpi_io ...
451! **************************************************************************************************
452 SUBROUTINE cp_forward_write_pw( &
453 self, &
454 pw, &
455 unit_nr, &
456 title, &
457 particles, &
458 zeff, &
459 stride, &
460 max_file_size_mb, &
461 zero_tails, &
462 silent, &
463 mpi_io &
464 )
465 CLASS(cp_section_key), INTENT(IN) :: self
466 TYPE(pw_r3d_rs_type), INTENT(IN) :: pw
467 INTEGER, INTENT(IN) :: unit_nr
468 CHARACTER(*), INTENT(IN), OPTIONAL :: title
469 TYPE(particle_list_type), POINTER :: particles
470 INTEGER, DIMENSION(:), OPTIONAL, POINTER :: stride
471 REAL(kind=dp), INTENT(IN), OPTIONAL :: max_file_size_mb
472 LOGICAL, INTENT(IN), OPTIONAL :: zero_tails, silent, mpi_io
473 REAL(kind=dp), DIMENSION(:), OPTIONAL :: zeff
474
475 IF (self%grid_output == grid_output_cubes) THEN
476 CALL cp_pw_to_cube(pw, unit_nr, title, particles, zeff, stride, max_file_size_mb, zero_tails, silent, mpi_io)
477 ELSE
478 CALL cp_pw_to_openpmd(pw, unit_nr, title, particles, zeff, stride, zero_tails, silent, mpi_io)
479 END IF
480 END SUBROUTINE cp_forward_write_pw
481
482! **************************************************************************************************
483!> \brief Forwards to either `cp_print_key_finished_output` or `cp_openpmd_print_key_finished_output`,
484!> depending on the configuration of the current base section.
485!> Closes either a Cube file or a reference to a section within an openPMD file.
486!> \param self ...
487!> \param unit_nr ...
488!> \param logger ...
489!> \param basis_section ...
490!> \param print_key_path ...
491!> \param local ...
492!> \param ignore_should_output ...
493!> \param on_file ...
494!> \param mpi_io ...
495! **************************************************************************************************
496 SUBROUTINE cp_forward_print_key_finished_output(self, unit_nr, logger, basis_section, &
497 print_key_path, local, ignore_should_output, on_file, &
498 mpi_io)
499 CLASS(cp_section_key), INTENT(IN) :: self
500 INTEGER, INTENT(INOUT) :: unit_nr
501 TYPE(cp_logger_type), POINTER :: logger
502 TYPE(section_vals_type), INTENT(IN) :: basis_section
503 CHARACTER(len=*), INTENT(IN), OPTIONAL :: print_key_path
504 LOGICAL, INTENT(IN), OPTIONAL :: local, ignore_should_output, on_file, &
505 mpi_io
506
507 IF (self%grid_output == grid_output_cubes) THEN
508 CALL cp_print_key_finished_output(unit_nr, logger, basis_section, print_key_path, local, ignore_should_output, on_file, mpi_io)
509 ELSE
510 CALL cp_openpmd_print_key_finished_output(unit_nr, logger, basis_section, print_key_path, local, ignore_should_output, mpi_io)
511 END IF
512 END SUBROUTINE cp_forward_print_key_finished_output
513
514 !
515! **************************************************************************************************
516!> \brief Decides if a particular output routine will write to openPMD, to Cube or to none.
517!> Writing to both is not supported.
518!> The distinction between Cube and openPMD output works such that the output configuration
519!> sections exist as duplicates: E.g. for DFT%PRINT%MO_CUBES,
520!> there additionally exists DFT%PRINT%MO_OPENPMD.
521!> The internal base configuration for such sections is identical; additionally there
522!> exist format-specific options such as APPEND for Cube or OPENPMD_CFG_FILE for openPMD.
523!> The routines in this file alternate between using relative section paths without the
524!> %DFT prefix (e.g. PRINT%MO_CUBES) or absolute section paths with the %DF% prefix
525!> (e.g. DFT%PRINT%MO_CUBES). Call this routine with the relative paths.
526!> \param input ...
527!> \param str_cubes ...
528!> \param str_openpmd ...
529!> \param logger ...
530!> \return ...
531! **************************************************************************************************
532 FUNCTION cube_or_openpmd(input, str_cubes, str_openpmd, logger) RESULT(res)
533 TYPE(section_vals_type), POINTER :: input
534 CHARACTER(len=*), INTENT(IN) :: str_cubes, str_openpmd
535 TYPE(cp_logger_type), POINTER :: logger
536 TYPE(cp_section_key) :: res
537
538 LOGICAL :: do_cubes, do_openpmd
539
540 do_cubes = btest(cp_print_key_should_output( &
541 logger%iter_info, input, &
542 "DFT%"//trim(adjustl(str_cubes))), cp_p_file)
543 do_openpmd = btest(cp_print_key_should_output( &
544 logger%iter_info, input, &
545 "DFT%"//trim(adjustl(str_openpmd))), cp_p_file)
546 ! Having Cube and openPMD output both active should be theoretically possible.
547 ! It would require some extra handling for the unit_nr return values.
548 ! (e.g. returning the Cube unit_nr and internally storing the associated openPMD unit_nr).
549 cpassert(.NOT. (do_cubes .AND. do_openpmd))
550 res%do_output = do_cubes .OR. do_openpmd
551 IF (do_openpmd) THEN
552 res%grid_output = grid_output_openpmd
553 res%relative_section_key = trim(adjustl(str_openpmd))
554 res%format_name = "openPMD"
555 ELSE
556 res%grid_output = grid_output_cubes
557 res%relative_section_key = trim(adjustl(str_cubes))
558 res%format_name = "Cube"
559 END IF
560 res%absolute_section_key = "DFT%"//trim(adjustl(res%relative_section_key))
561 END FUNCTION cube_or_openpmd
562
563! **************************************************************************************************
564!> \brief This section key is named WRITE_CUBE for Cube which does not make much sense
565!> for openPMD, so this key name has to be distinguished.
566!> \param grid_output ...
567!> \return ...
568! **************************************************************************************************
569 FUNCTION section_key_do_write(grid_output) RESULT(res)
570 INTEGER, INTENT(IN) :: grid_output
571 CHARACTER(len=32) :: res
572
573 IF (grid_output == grid_output_cubes) THEN
574 res = "%WRITE_CUBE"
575 ELSE IF (grid_output == grid_output_openpmd) THEN
576 res = "%WRITE_OPENPMD"
577 END IF
578 END FUNCTION section_key_do_write
579
580! **************************************************************************************************
581!> \brief Prints the output message for density file writing
582!> \param output_unit Unit number for output
583!> \param prefix The message prefix (e.g., "The total electron density")
584!> \param e_density_section Section key containing grid_output and format_name
585!> \param filename The actual filename or pattern used
586! **************************************************************************************************
587 SUBROUTINE print_density_output_message(output_unit, prefix, e_density_section, filename)
588 INTEGER, INTENT(IN) :: output_unit
589 CHARACTER(len=*), INTENT(IN) :: prefix
590 TYPE(cp_section_key), INTENT(IN) :: e_density_section
591 CHARACTER(len=*), INTENT(IN) :: filename
592
593 IF (e_density_section%grid_output == grid_output_openpmd) THEN
594 WRITE (unit=output_unit, fmt="(/,T2,A)") &
595 trim(prefix)//" is written in " &
596 //e_density_section%format_name &
597 //" file format to the file / file pattern:", &
598 trim(filename)
599 ELSE
600 WRITE (unit=output_unit, fmt="(/,T2,A,/,/,T2,A)") &
601 trim(prefix)//" is written in " &
602 //e_density_section%format_name &
603 //" file format to the file:", &
604 trim(filename)
605 END IF
606 END SUBROUTINE print_density_output_message
607
608! **************************************************************************************************
609!> \brief collects possible post - scf calculations and prints info / computes properties.
610!> \param qs_env the qs_env in which the qs_env lives
611!> \param wf_type ...
612!> \param do_mp2 ...
613!> \par History
614!> 02.2003 created [fawzi]
615!> 10.2004 moved here from qs_scf [Joost VandeVondele]
616!> started splitting out different subroutines
617!> 10.2015 added header for wave-function correlated methods [Vladimir Rybkin]
618!> \author fawzi
619!> \note
620!> this function changes mo_eigenvectors and mo_eigenvalues, depending on the print keys.
621!> In particular, MO_CUBES causes the MOs to be rotated to make them eigenstates of the KS
622!> matrix, and mo_eigenvalues is updated accordingly. This can, for unconverged wavefunctions,
623!> change afterwards slightly the forces (hence small numerical differences between MD
624!> with and without the debug print level). Ideally this should not happen...
625! **************************************************************************************************
626 SUBROUTINE scf_post_calculation_gpw(qs_env, wf_type, do_mp2)
627
628 TYPE(qs_environment_type), POINTER :: qs_env
629 CHARACTER(6), OPTIONAL :: wf_type
630 LOGICAL, OPTIONAL :: do_mp2
631
632 CHARACTER(len=*), PARAMETER :: routinen = 'scf_post_calculation_gpw', &
633 warning_cube_kpoint = "Print MO cubes not implemented for k-point calculations", &
634 warning_openpmd_kpoint = "Writing to openPMD not implemented for k-point calculations"
635
636 INTEGER :: handle, homo, ispin, min_lumos, n_rep, &
637 nchk_nmoloc, nhomo, nlumo, nlumo_stm, &
638 nlumos, nmo, nspins, output_unit, &
639 unit_nr
640 INTEGER, DIMENSION(:, :, :), POINTER :: marked_states
641 LOGICAL :: check_write, compute_lumos, do_homo, do_kpoints, do_mixed, do_stm, &
642 do_wannier_cubes, has_homo, has_lumo, loc_explicit, loc_print_explicit, my_do_mp2, &
643 my_localized_wfn, p_loc, p_loc_homo, p_loc_lumo, p_loc_mixed
644 REAL(dp) :: e_kin
645 REAL(kind=dp) :: gap, homo_lumo(2, 2), total_zeff_corr
646 REAL(kind=dp), DIMENSION(:), POINTER :: mo_eigenvalues
647 TYPE(admm_type), POINTER :: admm_env
648 TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
649 TYPE(cp_1d_r_p_type), DIMENSION(:), POINTER :: mixed_evals, occupied_evals, &
650 unoccupied_evals, unoccupied_evals_stm
651 TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:) :: mixed_orbs, occupied_orbs
652 TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:), &
653 TARGET :: homo_localized, lumo_localized, &
654 mixed_localized
655 TYPE(cp_fm_type), DIMENSION(:), POINTER :: lumo_ptr, mo_loc_history, &
656 unoccupied_orbs, unoccupied_orbs_stm
657 TYPE(cp_fm_type), POINTER :: mo_coeff
658 TYPE(cp_logger_type), POINTER :: logger
659 TYPE(cp_section_key) :: mo_section
660 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: ks_rmpv, matrix_p_mp2, matrix_s, &
661 mo_derivs
662 TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: kinetic_m, rho_ao
663 TYPE(dft_control_type), POINTER :: dft_control
664 TYPE(mo_set_type), DIMENSION(:), POINTER :: mos
665 TYPE(molecule_type), POINTER :: molecule_set(:)
666 TYPE(mp_para_env_type), POINTER :: para_env
667 TYPE(particle_list_type), POINTER :: particles
668 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
669 TYPE(pw_c1d_gs_type) :: wf_g
670 TYPE(pw_env_type), POINTER :: pw_env
671 TYPE(pw_pool_p_type), DIMENSION(:), POINTER :: pw_pools
672 TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
673 TYPE(pw_r3d_rs_type) :: wf_r
674 TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
675 TYPE(qs_loc_env_type), POINTER :: qs_loc_env_homo, qs_loc_env_lumo, &
676 qs_loc_env_mixed
677 TYPE(qs_rho_type), POINTER :: rho
678 TYPE(qs_scf_env_type), POINTER :: scf_env
679 TYPE(qs_subsys_type), POINTER :: subsys
680 TYPE(rtp_control_type), POINTER :: rtp_control
681 TYPE(scf_control_type), POINTER :: scf_control
682 TYPE(section_vals_type), POINTER :: dft_section, input, loc_print_section, &
683 localize_section, print_key, &
684 stm_section
685
686 CALL timeset(routinen, handle)
687
688 logger => cp_get_default_logger()
689 output_unit = cp_logger_get_default_io_unit(logger)
690
691 ! Print out the type of wavefunction to distinguish between SCF and post-SCF
692 my_do_mp2 = .false.
693 IF (PRESENT(do_mp2)) my_do_mp2 = do_mp2
694 IF (PRESENT(wf_type)) THEN
695 IF (output_unit > 0) THEN
696 WRITE (unit=output_unit, fmt='(/,(T1,A))') repeat("-", 40)
697 WRITE (unit=output_unit, fmt='(/,(T3,A,T19,A,T25,A))') "Properties from ", wf_type, " density"
698 WRITE (unit=output_unit, fmt='(/,(T1,A))') repeat("-", 40)
699 END IF
700 END IF
701
702 ! Writes the data that is already available in qs_env
703 CALL get_qs_env(qs_env, scf_env=scf_env)
704
705 my_localized_wfn = .false.
706 NULLIFY (admm_env, dft_control, pw_env, auxbas_pw_pool, pw_pools, mos, rho, &
707 mo_coeff, ks_rmpv, matrix_s, qs_loc_env_homo, qs_loc_env_lumo, scf_control, &
708 unoccupied_orbs, mo_eigenvalues, unoccupied_evals, &
709 unoccupied_evals_stm, molecule_set, mo_derivs, &
710 subsys, particles, input, print_key, kinetic_m, marked_states, &
711 mixed_evals, qs_loc_env_mixed)
712 NULLIFY (lumo_ptr, rho_ao)
713
714 has_homo = .false.
715 has_lumo = .false.
716 p_loc = .false.
717 p_loc_homo = .false.
718 p_loc_lumo = .false.
719 p_loc_mixed = .false.
720
721 cpassert(ASSOCIATED(scf_env))
722 cpassert(ASSOCIATED(qs_env))
723 ! Here we start with data that needs a postprocessing...
724 CALL get_qs_env(qs_env, &
725 dft_control=dft_control, &
726 molecule_set=molecule_set, &
727 scf_control=scf_control, &
728 do_kpoints=do_kpoints, &
729 input=input, &
730 subsys=subsys, &
731 rho=rho, &
732 pw_env=pw_env, &
733 particle_set=particle_set, &
734 atomic_kind_set=atomic_kind_set, &
735 qs_kind_set=qs_kind_set)
736 rtp_control => dft_control%rtp_control
737 CALL qs_subsys_get(subsys, particles=particles)
738
739 CALL qs_rho_get(rho, rho_ao_kp=rho_ao)
740
741 IF (my_do_mp2) THEN
742 ! Get the HF+MP2 density
743 CALL get_qs_env(qs_env, matrix_p_mp2=matrix_p_mp2)
744 DO ispin = 1, dft_control%nspins
745 CALL dbcsr_add(rho_ao(ispin, 1)%matrix, matrix_p_mp2(ispin)%matrix, 1.0_dp, 1.0_dp)
746 END DO
747 CALL qs_rho_update_rho(rho, qs_env=qs_env)
748 CALL qs_ks_did_change(qs_env%ks_env, rho_changed=.true.)
749 ! In MP2 case update the Hartree potential
750 CALL update_hartree_with_mp2(rho, qs_env)
751 END IF
752
753 CALL write_available_results(qs_env, scf_env)
754
755 ! **** the kinetic energy
756 IF (cp_print_key_should_output(logger%iter_info, input, &
757 "DFT%PRINT%KINETIC_ENERGY") /= 0) THEN
758 CALL get_qs_env(qs_env, kinetic_kp=kinetic_m)
759 cpassert(ASSOCIATED(kinetic_m))
760 cpassert(ASSOCIATED(kinetic_m(1, 1)%matrix))
761 CALL calculate_ptrace(kinetic_m, rho_ao, e_kin, dft_control%nspins)
762 unit_nr = cp_print_key_unit_nr(logger, input, "DFT%PRINT%KINETIC_ENERGY", &
763 extension=".Log")
764 IF (unit_nr > 0) THEN
765 WRITE (unit_nr, '(T3,A,T55,F25.14)') "Electronic kinetic energy:", e_kin
766 END IF
767 CALL cp_print_key_finished_output(unit_nr, logger, input, &
768 "DFT%PRINT%KINETIC_ENERGY")
769 END IF
770
771 ! Atomic Charges that require further computation
772 CALL qs_scf_post_charges(input, logger, qs_env)
773
774 ! Moments of charge distribution
775 CALL qs_scf_post_moments(input, logger, qs_env, output_unit)
776
777 ! Determine if we need to computer properties using the localized centers
778 dft_section => section_vals_get_subs_vals(input, "DFT")
779 localize_section => section_vals_get_subs_vals(dft_section, "LOCALIZE")
780 loc_print_section => section_vals_get_subs_vals(localize_section, "PRINT")
781 CALL section_vals_get(localize_section, explicit=loc_explicit)
782 CALL section_vals_get(loc_print_section, explicit=loc_print_explicit)
783
784 ! Print_keys controlled by localization
785 IF (loc_print_explicit) THEN
786 print_key => section_vals_get_subs_vals(loc_print_section, "MOLECULAR_DIPOLES")
787 p_loc = btest(cp_print_key_should_output(logger%iter_info, print_key), cp_p_file)
788 print_key => section_vals_get_subs_vals(loc_print_section, "TOTAL_DIPOLE")
789 p_loc = p_loc .OR. btest(cp_print_key_should_output(logger%iter_info, print_key), cp_p_file)
790 print_key => section_vals_get_subs_vals(loc_print_section, "WANNIER_CENTERS")
791 p_loc = p_loc .OR. btest(cp_print_key_should_output(logger%iter_info, print_key), cp_p_file)
792 print_key => section_vals_get_subs_vals(loc_print_section, "WANNIER_SPREADS")
793 p_loc = p_loc .OR. btest(cp_print_key_should_output(logger%iter_info, print_key), cp_p_file)
794 print_key => section_vals_get_subs_vals(loc_print_section, "WANNIER_CUBES")
795 p_loc = p_loc .OR. btest(cp_print_key_should_output(logger%iter_info, print_key), cp_p_file)
796 print_key => section_vals_get_subs_vals(loc_print_section, "MOLECULAR_STATES")
797 p_loc = p_loc .OR. btest(cp_print_key_should_output(logger%iter_info, print_key), cp_p_file)
798 print_key => section_vals_get_subs_vals(loc_print_section, "MOLECULAR_MOMENTS")
799 p_loc = p_loc .OR. btest(cp_print_key_should_output(logger%iter_info, print_key), cp_p_file)
800 print_key => section_vals_get_subs_vals(loc_print_section, "LOCALIZED_MOMENTS")
801 p_loc = p_loc .OR. btest(cp_print_key_should_output(logger%iter_info, print_key), cp_p_file)
802 print_key => section_vals_get_subs_vals(loc_print_section, "WANNIER_STATES")
803 p_loc = p_loc .OR. btest(cp_print_key_should_output(logger%iter_info, print_key), cp_p_file)
804 ELSE
805 p_loc = .false.
806 END IF
807 IF (loc_explicit) THEN
808 p_loc_homo = (section_get_ival(localize_section, "STATES") == do_loc_homo .OR. &
809 section_get_ival(localize_section, "STATES") == do_loc_both) .AND. p_loc
810 p_loc_lumo = (section_get_ival(localize_section, "STATES") == do_loc_lumo .OR. &
811 section_get_ival(localize_section, "STATES") == do_loc_both) .AND. p_loc
812 p_loc_mixed = (section_get_ival(localize_section, "STATES") == do_loc_mixed) .AND. p_loc
813 CALL section_vals_val_get(localize_section, "LIST_UNOCCUPIED", n_rep_val=n_rep)
814 ELSE
815 p_loc_homo = .false.
816 p_loc_lumo = .false.
817 p_loc_mixed = .false.
818 n_rep = 0
819 END IF
820
821 IF (n_rep == 0 .AND. p_loc_lumo) THEN
822 CALL cp_abort(__location__, "No LIST_UNOCCUPIED was specified, "// &
823 "therefore localization of unoccupied states will be skipped!")
824 p_loc_lumo = .false.
825 END IF
826
827 ! Control for STM
828 stm_section => section_vals_get_subs_vals(input, "DFT%PRINT%STM")
829 CALL section_vals_get(stm_section, explicit=do_stm)
830 nlumo_stm = 0
831 IF (do_stm) nlumo_stm = section_get_ival(stm_section, "NLUMO")
832
833 ! check for CUBES or openPMD (MOs and WANNIERS)
834 mo_section = cube_or_openpmd(input, str_mo_cubes, str_mo_openpmd, logger)
835
836 IF (loc_print_explicit) THEN
837 do_wannier_cubes = btest(cp_print_key_should_output(logger%iter_info, loc_print_section, &
838 "WANNIER_CUBES"), cp_p_file)
839 ELSE
840 do_wannier_cubes = .false.
841 END IF
842 nlumo = section_get_ival(dft_section, mo_section%concat_to_relative("%NLUMO"))
843 nhomo = section_get_ival(dft_section, mo_section%concat_to_relative("%NHOMO"))
844
845 ! Setup the grids needed to compute a wavefunction given a vector..
846 IF (((mo_section%do_output .OR. do_wannier_cubes) .AND. (nlumo /= 0 .OR. nhomo /= 0)) .OR. p_loc) THEN
847 CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool, &
848 pw_pools=pw_pools)
849 CALL auxbas_pw_pool%create_pw(wf_r)
850 CALL auxbas_pw_pool%create_pw(wf_g)
851 END IF
852
853 IF (dft_control%restricted) THEN
854 !For ROKS useful only first term
855 nspins = 1
856 ELSE
857 nspins = dft_control%nspins
858 END IF
859 !Some info about ROKS
860 IF (dft_control%restricted .AND. (mo_section%do_output .OR. p_loc_homo)) THEN
861 CALL cp_abort(__location__, "Unclear how we define MOs / localization in the restricted case ... ")
862 ! It is possible to obtain Wannier centers for ROKS without rotations for SINGLE OCCUPIED ORBITALS
863 END IF
864 ! Makes the MOs eigenstates, computes eigenvalues, write cubes
865 IF (do_kpoints) THEN
866 cpwarn_if(mo_section%do_cubes(), warning_cube_kpoint)
867 cpwarn_if(mo_section%do_openpmd(), warning_openpmd_kpoint)
868 ELSE
869 CALL get_qs_env(qs_env, &
870 mos=mos, &
871 matrix_ks=ks_rmpv)
872 IF ((mo_section%do_output .AND. nhomo /= 0) .OR. do_stm) THEN
873 CALL get_qs_env(qs_env, mo_derivs=mo_derivs)
874 IF (dft_control%do_admm) THEN
875 CALL get_qs_env(qs_env, admm_env=admm_env)
876 CALL make_mo_eig(mos, nspins, ks_rmpv, scf_control, mo_derivs, admm_env=admm_env)
877 ELSE
878 IF (dft_control%hairy_probes) THEN
879 scf_control%smear%do_smear = .false.
880 CALL make_mo_eig(mos, dft_control%nspins, ks_rmpv, scf_control, mo_derivs, &
881 hairy_probes=dft_control%hairy_probes, &
882 probe=dft_control%probe)
883 ELSE
884 CALL make_mo_eig(mos, dft_control%nspins, ks_rmpv, scf_control, mo_derivs)
885 END IF
886 END IF
887 DO ispin = 1, dft_control%nspins
888 CALL get_mo_set(mo_set=mos(ispin), eigenvalues=mo_eigenvalues, homo=homo)
889 homo_lumo(ispin, 1) = mo_eigenvalues(homo)
890 END DO
891 has_homo = .true.
892 END IF
893 IF (mo_section%do_output .AND. nhomo /= 0) THEN
894 DO ispin = 1, nspins
895 ! Prints the cube files of OCCUPIED ORBITALS
896 CALL get_mo_set(mo_set=mos(ispin), mo_coeff=mo_coeff, &
897 eigenvalues=mo_eigenvalues, homo=homo, nmo=nmo)
898 CALL qs_scf_post_occ_cubes(input, dft_section, dft_control, logger, qs_env, &
899 mo_coeff, wf_g, wf_r, particles, homo, ispin, mo_section)
900 END DO
901 END IF
902 END IF
903
904 ! Initialize the localization environment, needed e.g. for wannier functions and molecular states
905 ! Gets localization info for the occupied orbs
906 ! - Possibly gets wannier functions
907 ! - Possibly gets molecular states
908 IF (p_loc_homo) THEN
909 IF (do_kpoints) THEN
910 cpwarn("Localization not implemented for k-point calculations!")
911 ELSE IF (dft_control%restricted &
912 .AND. (section_get_ival(localize_section, "METHOD") /= do_loc_none) &
913 .AND. (section_get_ival(localize_section, "METHOD") /= do_loc_jacobi)) THEN
914 cpabort("ROKS works only with LOCALIZE METHOD NONE or JACOBI")
915 ELSE
916 ALLOCATE (occupied_orbs(dft_control%nspins))
917 ALLOCATE (occupied_evals(dft_control%nspins))
918 ALLOCATE (homo_localized(dft_control%nspins))
919 DO ispin = 1, dft_control%nspins
920 CALL get_mo_set(mo_set=mos(ispin), mo_coeff=mo_coeff, &
921 eigenvalues=mo_eigenvalues)
922 occupied_orbs(ispin) = mo_coeff
923 occupied_evals(ispin)%array => mo_eigenvalues
924 CALL cp_fm_create(homo_localized(ispin), occupied_orbs(ispin)%matrix_struct)
925 CALL cp_fm_to_fm(occupied_orbs(ispin), homo_localized(ispin))
926 END DO
927
928 CALL get_qs_env(qs_env, mo_loc_history=mo_loc_history)
929 do_homo = .true.
930
931 ALLOCATE (qs_loc_env_homo)
932 CALL qs_loc_env_create(qs_loc_env_homo)
933 CALL qs_loc_control_init(qs_loc_env_homo, localize_section, do_homo=do_homo)
934 CALL qs_loc_init(qs_env, qs_loc_env_homo, localize_section, homo_localized, do_homo, &
935 mo_section%do_output, mo_loc_history=mo_loc_history)
936 CALL get_localization_info(qs_env, qs_loc_env_homo, localize_section, homo_localized, &
937 wf_r, wf_g, particles, occupied_orbs, occupied_evals, marked_states)
938
939 !retain the homo_localized for future use
940 IF (qs_loc_env_homo%localized_wfn_control%use_history) THEN
941 CALL retain_history(mo_loc_history, homo_localized)
942 CALL set_qs_env(qs_env, mo_loc_history=mo_loc_history)
943 END IF
944
945 !write restart for localization of occupied orbitals
946 CALL loc_write_restart(qs_loc_env_homo, loc_print_section, mos, &
947 homo_localized, do_homo)
948 CALL cp_fm_release(homo_localized)
949 DEALLOCATE (occupied_orbs)
950 DEALLOCATE (occupied_evals)
951 ! Print Total Dipole if the localization has been performed
952 IF (qs_loc_env_homo%do_localize) THEN
953 CALL loc_dipole(input, dft_control, qs_loc_env_homo, logger, qs_env)
954 END IF
955 END IF
956 END IF
957
958 ! Gets the lumos, and eigenvalues for the lumos, and localize them if requested
959 IF (do_kpoints) THEN
960 IF (mo_section%do_output .OR. p_loc_lumo) THEN
961 ! nothing at the moment, not implemented
962 cpwarn("Localization and MO related output not implemented for k-point calculations!")
963 END IF
964 ELSE
965 compute_lumos = mo_section%do_output .AND. nlumo /= 0
966 compute_lumos = compute_lumos .OR. p_loc_lumo
967
968 DO ispin = 1, dft_control%nspins
969 CALL get_mo_set(mo_set=mos(ispin), homo=homo, nmo=nmo)
970 compute_lumos = compute_lumos .AND. homo == nmo
971 END DO
972
973 IF (mo_section%do_output .AND. .NOT. compute_lumos) THEN
974
975 nlumo = section_get_ival(dft_section, mo_section%concat_to_relative("%NLUMO"))
976 DO ispin = 1, dft_control%nspins
977
978 CALL get_mo_set(mo_set=mos(ispin), homo=homo, nmo=nmo, eigenvalues=mo_eigenvalues)
979 IF (nlumo > nmo - homo) THEN
980 ! this case not yet implemented
981 ELSE
982 IF (nlumo == -1) THEN
983 nlumo = nmo - homo
984 END IF
985 IF (output_unit > 0) WRITE (output_unit, *) " "
986 IF (output_unit > 0) WRITE (output_unit, *) " Lowest eigenvalues of the unoccupied subspace spin ", ispin
987 IF (output_unit > 0) WRITE (output_unit, *) "---------------------------------------------"
988 IF (output_unit > 0) WRITE (output_unit, '(4(1X,1F16.8))') mo_eigenvalues(homo + 1:homo + nlumo)
989
990 ! Prints the cube files of UNOCCUPIED ORBITALS
991 CALL get_mo_set(mo_set=mos(ispin), mo_coeff=mo_coeff)
992 CALL qs_scf_post_unocc_cubes(input, dft_section, dft_control, logger, qs_env, &
993 mo_coeff, wf_g, wf_r, particles, nlumo, homo, ispin, lumo=homo + 1, mo_section=mo_section)
994 END IF
995 END DO
996
997 END IF
998
999 IF (compute_lumos) THEN
1000 check_write = .true.
1001 min_lumos = nlumo
1002 IF (nlumo == 0) check_write = .false.
1003 IF (p_loc_lumo) THEN
1004 do_homo = .false.
1005 ALLOCATE (qs_loc_env_lumo)
1006 CALL qs_loc_env_create(qs_loc_env_lumo)
1007 CALL qs_loc_control_init(qs_loc_env_lumo, localize_section, do_homo=do_homo)
1008 min_lumos = max(maxval(qs_loc_env_lumo%localized_wfn_control%loc_states(:, :)), nlumo)
1009 END IF
1010
1011 ALLOCATE (unoccupied_orbs(dft_control%nspins))
1012 ALLOCATE (unoccupied_evals(dft_control%nspins))
1013 CALL make_lumo_gpw(qs_env, scf_env, unoccupied_orbs, unoccupied_evals, min_lumos, nlumos)
1014 lumo_ptr => unoccupied_orbs
1015 DO ispin = 1, dft_control%nspins
1016 has_lumo = .true.
1017 homo_lumo(ispin, 2) = unoccupied_evals(ispin)%array(1)
1018 CALL get_mo_set(mo_set=mos(ispin), homo=homo)
1019 IF (check_write) THEN
1020 IF (p_loc_lumo .AND. nlumo /= -1) nlumos = min(nlumo, nlumos)
1021 ! Prints the cube files of UNOCCUPIED ORBITALS
1022 CALL qs_scf_post_unocc_cubes(input, dft_section, dft_control, logger, qs_env, &
1023 unoccupied_orbs(ispin), wf_g, wf_r, particles, nlumos, homo, ispin, mo_section=mo_section)
1024 END IF
1025 END DO
1026
1027 IF (p_loc_lumo) THEN
1028 ALLOCATE (lumo_localized(dft_control%nspins))
1029 DO ispin = 1, dft_control%nspins
1030 CALL cp_fm_create(lumo_localized(ispin), unoccupied_orbs(ispin)%matrix_struct)
1031 CALL cp_fm_to_fm(unoccupied_orbs(ispin), lumo_localized(ispin))
1032 END DO
1033 CALL qs_loc_init(qs_env, qs_loc_env_lumo, localize_section, lumo_localized, do_homo, mo_section%do_output, &
1034 evals=unoccupied_evals)
1035 CALL qs_loc_env_init(qs_loc_env_lumo, qs_loc_env_lumo%localized_wfn_control, qs_env, &
1036 loc_coeff=unoccupied_orbs)
1037 CALL get_localization_info(qs_env, qs_loc_env_lumo, localize_section, &
1038 lumo_localized, wf_r, wf_g, particles, &
1039 unoccupied_orbs, unoccupied_evals, marked_states)
1040 CALL loc_write_restart(qs_loc_env_lumo, loc_print_section, mos, homo_localized, do_homo, &
1041 evals=unoccupied_evals)
1042 lumo_ptr => lumo_localized
1043 END IF
1044 END IF
1045
1046 IF (has_homo .AND. has_lumo) THEN
1047 IF (output_unit > 0) WRITE (output_unit, *) " "
1048 DO ispin = 1, dft_control%nspins
1049 IF (.NOT. scf_control%smear%do_smear) THEN
1050 gap = homo_lumo(ispin, 2) - homo_lumo(ispin, 1)
1051 IF (output_unit > 0) WRITE (output_unit, '(T2,A,F12.6)') &
1052 "HOMO - LUMO gap [eV] :", gap*evolt
1053 END IF
1054 END DO
1055 END IF
1056 END IF
1057
1058 IF (p_loc_mixed) THEN
1059 IF (do_kpoints) THEN
1060 cpwarn("Localization not implemented for k-point calculations!")
1061 ELSE IF (dft_control%restricted) THEN
1062 IF (output_unit > 0) WRITE (output_unit, *) &
1063 " Unclear how we define MOs / localization in the restricted case... skipping"
1064 ELSE
1065
1066 ALLOCATE (mixed_orbs(dft_control%nspins))
1067 ALLOCATE (mixed_evals(dft_control%nspins))
1068 ALLOCATE (mixed_localized(dft_control%nspins))
1069 DO ispin = 1, dft_control%nspins
1070 CALL get_mo_set(mo_set=mos(ispin), mo_coeff=mo_coeff, &
1071 eigenvalues=mo_eigenvalues)
1072 mixed_orbs(ispin) = mo_coeff
1073 mixed_evals(ispin)%array => mo_eigenvalues
1074 CALL cp_fm_create(mixed_localized(ispin), mixed_orbs(ispin)%matrix_struct)
1075 CALL cp_fm_to_fm(mixed_orbs(ispin), mixed_localized(ispin))
1076 END DO
1077
1078 CALL get_qs_env(qs_env, mo_loc_history=mo_loc_history)
1079 do_homo = .false.
1080 do_mixed = .true.
1081 total_zeff_corr = scf_env%sum_zeff_corr
1082 ALLOCATE (qs_loc_env_mixed)
1083 CALL qs_loc_env_create(qs_loc_env_mixed)
1084 CALL qs_loc_control_init(qs_loc_env_mixed, localize_section, do_homo=do_homo, do_mixed=do_mixed)
1085 CALL qs_loc_init(qs_env, qs_loc_env_mixed, localize_section, mixed_localized, do_homo, &
1086 mo_section%do_output, mo_loc_history=mo_loc_history, tot_zeff_corr=total_zeff_corr, &
1088
1089 DO ispin = 1, dft_control%nspins
1090 CALL cp_fm_get_info(mixed_localized(ispin), ncol_global=nchk_nmoloc)
1091 END DO
1092
1093 CALL get_localization_info(qs_env, qs_loc_env_mixed, localize_section, mixed_localized, &
1094 wf_r, wf_g, particles, mixed_orbs, mixed_evals, marked_states)
1095
1096 !retain the homo_localized for future use
1097 IF (qs_loc_env_mixed%localized_wfn_control%use_history) THEN
1098 CALL retain_history(mo_loc_history, mixed_localized)
1099 CALL set_qs_env(qs_env, mo_loc_history=mo_loc_history)
1100 END IF
1101
1102 !write restart for localization of occupied orbitals
1103 CALL loc_write_restart(qs_loc_env_mixed, loc_print_section, mos, &
1104 mixed_localized, do_homo, do_mixed=do_mixed)
1105 CALL cp_fm_release(mixed_localized)
1106 DEALLOCATE (mixed_orbs)
1107 DEALLOCATE (mixed_evals)
1108 END IF
1109 END IF
1110
1111 ! Deallocate grids needed to compute wavefunctions
1112 IF (((mo_section%do_output .OR. do_wannier_cubes) .AND. (nlumo /= 0 .OR. nhomo /= 0)) .OR. p_loc) THEN
1113 CALL auxbas_pw_pool%give_back_pw(wf_r)
1114 CALL auxbas_pw_pool%give_back_pw(wf_g)
1115 END IF
1116
1117 ! Destroy the localization environment
1118 IF (.NOT. do_kpoints) THEN
1119 IF (p_loc_homo) THEN
1120 CALL qs_loc_env_release(qs_loc_env_homo)
1121 DEALLOCATE (qs_loc_env_homo)
1122 END IF
1123 IF (p_loc_lumo) THEN
1124 CALL qs_loc_env_release(qs_loc_env_lumo)
1125 DEALLOCATE (qs_loc_env_lumo)
1126 END IF
1127 IF (p_loc_mixed) THEN
1128 CALL qs_loc_env_release(qs_loc_env_mixed)
1129 DEALLOCATE (qs_loc_env_mixed)
1130 END IF
1131 END IF
1132
1133 ! generate a mix of wfns, and write to a restart
1134 IF (do_kpoints) THEN
1135 ! nothing at the moment, not implemented
1136 ELSE
1137 CALL get_qs_env(qs_env, matrix_s=matrix_s, para_env=para_env)
1138 CALL wfn_mix(mos, particle_set, dft_section, qs_kind_set, para_env, &
1139 output_unit, unoccupied_orbs=lumo_ptr, scf_env=scf_env, &
1140 matrix_s=matrix_s, marked_states=marked_states)
1141
1142 IF (p_loc_lumo) CALL cp_fm_release(lumo_localized)
1143 END IF
1144 IF (ASSOCIATED(marked_states)) THEN
1145 DEALLOCATE (marked_states)
1146 END IF
1147
1148 ! This is just a deallocation for printing MO_CUBES or TDDFPT
1149 IF (.NOT. do_kpoints) THEN
1150 IF (compute_lumos) THEN
1151 DO ispin = 1, dft_control%nspins
1152 DEALLOCATE (unoccupied_evals(ispin)%array)
1153 CALL cp_fm_release(unoccupied_orbs(ispin))
1154 END DO
1155 DEALLOCATE (unoccupied_evals)
1156 DEALLOCATE (unoccupied_orbs)
1157 END IF
1158 END IF
1159
1160 !stm images
1161 IF (do_stm) THEN
1162 IF (do_kpoints) THEN
1163 cpwarn("STM not implemented for k-point calculations!")
1164 ELSE
1165 NULLIFY (unoccupied_orbs_stm, unoccupied_evals_stm)
1166 IF (nlumo_stm > 0) THEN
1167 ALLOCATE (unoccupied_orbs_stm(dft_control%nspins))
1168 ALLOCATE (unoccupied_evals_stm(dft_control%nspins))
1169 CALL make_lumo_gpw(qs_env, scf_env, unoccupied_orbs_stm, unoccupied_evals_stm, &
1170 nlumo_stm, nlumos)
1171 END IF
1172
1173 CALL th_stm_image(qs_env, stm_section, particles, unoccupied_orbs_stm, &
1174 unoccupied_evals_stm)
1175
1176 IF (nlumo_stm > 0) THEN
1177 DO ispin = 1, dft_control%nspins
1178 DEALLOCATE (unoccupied_evals_stm(ispin)%array)
1179 END DO
1180 DEALLOCATE (unoccupied_evals_stm)
1181 CALL cp_fm_release(unoccupied_orbs_stm)
1182 END IF
1183 END IF
1184 END IF
1185
1186 ! Print coherent X-ray diffraction spectrum
1187 CALL qs_scf_post_xray(input, dft_section, logger, qs_env, output_unit)
1188
1189 ! Calculation of Electric Field Gradients
1190 CALL qs_scf_post_efg(input, logger, qs_env)
1191
1192 ! Calculation of ET
1193 CALL qs_scf_post_et(input, qs_env, dft_control)
1194
1195 ! Calculation of EPR Hyperfine Coupling Tensors
1196 CALL qs_scf_post_epr(input, logger, qs_env)
1197
1198 ! Calculation of properties needed for BASIS_MOLOPT optimizations
1199 CALL qs_scf_post_molopt(input, logger, qs_env)
1200
1201 ! Calculate ELF
1202 CALL qs_scf_post_elf(input, logger, qs_env)
1203
1204 ! Use Wannier90 interface
1205 CALL wannier90_interface(input, logger, qs_env)
1206
1207 IF (my_do_mp2) THEN
1208 ! Get everything back
1209 DO ispin = 1, dft_control%nspins
1210 CALL dbcsr_add(rho_ao(ispin, 1)%matrix, matrix_p_mp2(ispin)%matrix, 1.0_dp, -1.0_dp)
1211 END DO
1212 CALL qs_rho_update_rho(rho, qs_env=qs_env)
1213 CALL qs_ks_did_change(qs_env%ks_env, rho_changed=.true.)
1214 END IF
1215
1217
1218 CALL timestop(handle)
1219
1220 END SUBROUTINE scf_post_calculation_gpw
1221
1222! **************************************************************************************************
1223!> \brief Gets the LUMOs and their eigenvalues for all spin channels.
1224!> \param qs_env ...
1225!> \param scf_env ...
1226!> \param unoccupied_orbs ...
1227!> \param unoccupied_evals ...
1228!> \param nlumo ...
1229!> \param nlumos ...
1230! **************************************************************************************************
1231 SUBROUTINE make_lumo_gpw(qs_env, scf_env, unoccupied_orbs, unoccupied_evals, nlumo, nlumos)
1232
1233 TYPE(qs_environment_type), POINTER :: qs_env
1234 TYPE(qs_scf_env_type), POINTER :: scf_env
1235 TYPE(cp_fm_type), DIMENSION(:), INTENT(INOUT) :: unoccupied_orbs
1236 TYPE(cp_1d_r_p_type), DIMENSION(:), POINTER :: unoccupied_evals
1237 INTEGER, INTENT(IN) :: nlumo
1238 INTEGER, INTENT(OUT) :: nlumos
1239
1240 CHARACTER(len=*), PARAMETER :: routinen = 'make_lumo_gpw'
1241
1242 INTEGER :: handle, homo, ispin, n, nao, nmo, &
1243 output_unit
1244 TYPE(admm_type), POINTER :: admm_env
1245 TYPE(cp_blacs_env_type), POINTER :: blacs_env
1246 TYPE(cp_fm_struct_type), POINTER :: fm_struct_tmp
1247 TYPE(cp_fm_type), POINTER :: mo_coeff
1248 TYPE(cp_logger_type), POINTER :: logger
1249 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: ks_rmpv, matrix_s
1250 TYPE(dft_control_type), POINTER :: dft_control
1251 TYPE(mo_set_type), DIMENSION(:), POINTER :: mos
1252 TYPE(mp_para_env_type), POINTER :: para_env
1253 TYPE(preconditioner_type), POINTER :: local_preconditioner
1254 TYPE(scf_control_type), POINTER :: scf_control
1255
1256 CALL timeset(routinen, handle)
1257
1258 NULLIFY (ks_rmpv, matrix_s, scf_control, dft_control, admm_env, para_env, blacs_env, mos)
1259 CALL get_qs_env(qs_env, &
1260 matrix_ks=ks_rmpv, &
1261 matrix_s=matrix_s, &
1262 scf_control=scf_control, &
1263 dft_control=dft_control, &
1264 admm_env=admm_env, &
1265 para_env=para_env, &
1266 blacs_env=blacs_env, &
1267 mos=mos)
1268
1269 logger => cp_get_default_logger()
1270 output_unit = cp_logger_get_default_io_unit(logger)
1271
1272 DO ispin = 1, dft_control%nspins
1273 NULLIFY (unoccupied_evals(ispin)%array)
1274 IF (output_unit > 0) WRITE (output_unit, *) " "
1275 IF (output_unit > 0) WRITE (output_unit, *) &
1276 " Using OT eigensolver for additional unoccupied orbitals spin ", ispin
1277 IF (output_unit > 0) WRITE (output_unit, *) &
1278 " Lowest Eigenvalues of the unoccupied subspace spin ", ispin
1279 IF (output_unit > 0) WRITE (output_unit, fmt='(1X,A)') "-----------------------------------------------------"
1280 CALL get_mo_set(mo_set=mos(ispin), mo_coeff=mo_coeff, homo=homo, nao=nao, nmo=nmo)
1281 CALL cp_fm_get_info(mo_coeff, nrow_global=n)
1282 nlumos = max(1, min(nlumo, nao - nmo))
1283 IF (nlumo == -1) nlumos = nao - nmo
1284 ALLOCATE (unoccupied_evals(ispin)%array(nlumos))
1285 CALL cp_fm_struct_create(fm_struct_tmp, para_env=para_env, context=blacs_env, &
1286 nrow_global=n, ncol_global=nlumos)
1287 CALL cp_fm_create(unoccupied_orbs(ispin), fm_struct_tmp, name="lumos")
1288 CALL cp_fm_struct_release(fm_struct_tmp)
1289 CALL cp_fm_init_random(unoccupied_orbs(ispin), nlumos)
1290
1291 ! the full_all preconditioner makes not much sense for lumos search
1292 NULLIFY (local_preconditioner)
1293 IF (ASSOCIATED(scf_env)) THEN
1294 IF (ASSOCIATED(scf_env%ot_preconditioner)) THEN
1295 local_preconditioner => scf_env%ot_preconditioner(1)%preconditioner
1296 ! this one can for sure not be right (as it has to match a given C0)
1297 IF (local_preconditioner%in_use == ot_precond_full_all) THEN
1298 NULLIFY (local_preconditioner)
1299 END IF
1300 END IF
1301 END IF
1302
1303 ! If we do ADMM, we add have to modify the Kohn-Sham matrix
1304 IF (dft_control%do_admm) THEN
1305 CALL admm_correct_for_eigenvalues(ispin, admm_env, ks_rmpv(ispin)%matrix)
1306 END IF
1307
1308 CALL ot_eigensolver(matrix_h=ks_rmpv(ispin)%matrix, matrix_s=matrix_s(1)%matrix, &
1309 matrix_c_fm=unoccupied_orbs(ispin), &
1310 matrix_orthogonal_space_fm=mo_coeff, &
1311 eps_gradient=scf_control%eps_lumos, &
1312 preconditioner=local_preconditioner, &
1313 iter_max=scf_control%max_iter_lumos, &
1314 size_ortho_space=nmo)
1315
1316 CALL calculate_subspace_eigenvalues(unoccupied_orbs(ispin), ks_rmpv(ispin)%matrix, &
1317 unoccupied_evals(ispin)%array, scr=output_unit, &
1318 ionode=output_unit > 0)
1319
1320 ! If we do ADMM, we restore the original Kohn-Sham matrix
1321 IF (dft_control%do_admm) THEN
1322 CALL admm_uncorrect_for_eigenvalues(ispin, admm_env, ks_rmpv(ispin)%matrix)
1323 END IF
1324
1325 END DO
1326
1327 CALL timestop(handle)
1328
1329 END SUBROUTINE make_lumo_gpw
1330
1331! **************************************************************************************************
1332!> \brief Computes and Prints Atomic Charges with several methods
1333!> \param input ...
1334!> \param logger ...
1335!> \param qs_env the qs_env in which the qs_env lives
1336! **************************************************************************************************
1337 SUBROUTINE qs_scf_post_charges(input, logger, qs_env)
1338 TYPE(section_vals_type), POINTER :: input
1339 TYPE(cp_logger_type), POINTER :: logger
1340 TYPE(qs_environment_type), POINTER :: qs_env
1341
1342 CHARACTER(len=*), PARAMETER :: routinen = 'qs_scf_post_charges'
1343
1344 INTEGER :: handle, print_level, unit_nr
1345 LOGICAL :: do_kpoints, print_it
1346 TYPE(section_vals_type), POINTER :: density_fit_section, print_key
1347
1348 CALL timeset(routinen, handle)
1349
1350 CALL get_qs_env(qs_env=qs_env, do_kpoints=do_kpoints)
1351
1352 ! Mulliken charges require no further computation and are printed from write_mo_free_results
1353
1354 ! Compute the Lowdin charges
1355 print_key => section_vals_get_subs_vals(input, "DFT%PRINT%LOWDIN")
1356 IF (btest(cp_print_key_should_output(logger%iter_info, print_key), cp_p_file)) THEN
1357 unit_nr = cp_print_key_unit_nr(logger, input, "DFT%PRINT%LOWDIN", extension=".lowdin", &
1358 log_filename=.false.)
1359 print_level = 1
1360 CALL section_vals_val_get(print_key, "PRINT_GOP", l_val=print_it)
1361 IF (print_it) print_level = 2
1362 CALL section_vals_val_get(print_key, "PRINT_ALL", l_val=print_it)
1363 IF (print_it) print_level = 3
1364 CALL lowdin_population_analysis(qs_env, unit_nr, print_level)
1365 CALL cp_print_key_finished_output(unit_nr, logger, input, "DFT%PRINT%LOWDIN")
1366 END IF
1367
1368 ! Compute the RESP charges
1369 CALL resp_fit(qs_env)
1370
1371 ! Compute the Density Derived Atomic Point charges with the Bloechl scheme
1372 print_key => section_vals_get_subs_vals(input, "PROPERTIES%FIT_CHARGE")
1373 IF (btest(cp_print_key_should_output(logger%iter_info, print_key), cp_p_file)) THEN
1374 unit_nr = cp_print_key_unit_nr(logger, input, "PROPERTIES%FIT_CHARGE", extension=".Fitcharge", &
1375 log_filename=.false.)
1376 density_fit_section => section_vals_get_subs_vals(input, "DFT%DENSITY_FITTING")
1377 CALL get_ddapc(qs_env, .false., density_fit_section, iwc=unit_nr)
1378 CALL cp_print_key_finished_output(unit_nr, logger, input, "PROPERTIES%FIT_CHARGE")
1379 END IF
1380
1381 CALL timestop(handle)
1382
1383 END SUBROUTINE qs_scf_post_charges
1384
1385! **************************************************************************************************
1386!> \brief Computes and prints the Cube Files for MO
1387!> \param input ...
1388!> \param dft_section ...
1389!> \param dft_control ...
1390!> \param logger ...
1391!> \param qs_env the qs_env in which the qs_env lives
1392!> \param mo_coeff ...
1393!> \param wf_g ...
1394!> \param wf_r ...
1395!> \param particles ...
1396!> \param homo ...
1397!> \param ispin ...
1398!> \param mo_section ...
1399! **************************************************************************************************
1400 SUBROUTINE qs_scf_post_occ_cubes(input, dft_section, dft_control, logger, qs_env, &
1401 mo_coeff, wf_g, wf_r, particles, homo, ispin, mo_section)
1402 TYPE(section_vals_type), POINTER :: input, dft_section
1403 TYPE(dft_control_type), POINTER :: dft_control
1404 TYPE(cp_logger_type), POINTER :: logger
1405 TYPE(qs_environment_type), POINTER :: qs_env
1406 TYPE(cp_fm_type), INTENT(IN) :: mo_coeff
1407 TYPE(pw_c1d_gs_type), INTENT(INOUT) :: wf_g
1408 TYPE(pw_r3d_rs_type), INTENT(INOUT) :: wf_r
1409 TYPE(particle_list_type), POINTER :: particles
1410 INTEGER, INTENT(IN) :: homo, ispin
1411 TYPE(cp_section_key) :: mo_section
1412
1413 CHARACTER(len=*), PARAMETER :: routinen = 'qs_scf_post_occ_cubes'
1414
1415 CHARACTER(LEN=default_path_length) :: filename, my_pos_cube, title
1416 INTEGER :: handle, i, ir, ivector, n_rep, nhomo, &
1417 nlist, unit_nr
1418 INTEGER, DIMENSION(:), POINTER :: list, list_index
1419 LOGICAL :: append_cube, mpi_io
1420 TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
1421 TYPE(cell_type), POINTER :: cell
1422 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
1423 TYPE(pw_env_type), POINTER :: pw_env
1424 TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
1425
1426 CALL timeset(routinen, handle)
1427
1428#ifndef __OPENPMD
1429 ! Error should usually be caught earlier as PRINT%MO_OPENPMD is not added to the input section
1430 ! if openPMD is not activated
1431 cpassert(mo_section%grid_output /= grid_output_openpmd)
1432#endif
1433
1434 NULLIFY (list_index)
1435
1436 IF (btest(cp_print_key_should_output(logger%iter_info, dft_section, mo_section%relative_section_key) &
1437 , cp_p_file) .AND. section_get_lval(dft_section, mo_section%concat_to_relative(section_key_do_write(mo_section%grid_output)))) THEN
1438 nhomo = section_get_ival(dft_section, mo_section%concat_to_relative("%NHOMO"))
1439 ! For openPMD, refer to access modes instead of APPEND key
1440 IF (mo_section%grid_output == grid_output_cubes) THEN
1441 append_cube = section_get_lval(dft_section, mo_section%concat_to_relative("%APPEND"))
1442 END IF
1443 my_pos_cube = "REWIND"
1444 IF (append_cube) THEN
1445 my_pos_cube = "APPEND"
1446 END IF
1447 CALL section_vals_val_get(dft_section, mo_section%concat_to_relative("%HOMO_LIST"), n_rep_val=n_rep)
1448 IF (n_rep > 0) THEN ! write the cubes of the list
1449 nlist = 0
1450 DO ir = 1, n_rep
1451 NULLIFY (list)
1452 CALL section_vals_val_get(dft_section, mo_section%concat_to_relative("%HOMO_LIST"), i_rep_val=ir, &
1453 i_vals=list)
1454 IF (ASSOCIATED(list)) THEN
1455 CALL reallocate(list_index, 1, nlist + SIZE(list))
1456 DO i = 1, SIZE(list)
1457 list_index(i + nlist) = list(i)
1458 END DO
1459 nlist = nlist + SIZE(list)
1460 END IF
1461 END DO
1462 ELSE
1463
1464 IF (nhomo == -1) nhomo = homo
1465 nlist = homo - max(1, homo - nhomo + 1) + 1
1466 ALLOCATE (list_index(nlist))
1467 DO i = 1, nlist
1468 list_index(i) = max(1, homo - nhomo + 1) + i - 1
1469 END DO
1470 END IF
1471 DO i = 1, nlist
1472 ivector = list_index(i)
1473 CALL get_qs_env(qs_env=qs_env, &
1474 atomic_kind_set=atomic_kind_set, &
1475 qs_kind_set=qs_kind_set, &
1476 cell=cell, &
1477 particle_set=particle_set, &
1478 pw_env=pw_env)
1479 CALL calculate_wavefunction(mo_coeff, ivector, wf_r, wf_g, atomic_kind_set, qs_kind_set, &
1480 cell, dft_control, particle_set, pw_env)
1481 WRITE (filename, '(a4,I5.5,a1,I1.1)') "WFN_", ivector, "_", ispin
1482 mpi_io = .true.
1483
1484 unit_nr = mo_section%print_key_unit_nr( &
1485 logger, &
1486 input, &
1487 mo_section%absolute_section_key, &
1488 extension=".cube", &
1489 middle_name=trim(filename), &
1490 file_position=my_pos_cube, &
1491 log_filename=.false., &
1492 mpi_io=mpi_io, &
1493 openpmd_basename="dft-mo", &
1494 openpmd_unit_dimension=openpmd_unit_dimension_wavefunction, &
1495 openpmd_unit_si=openpmd_unit_si_wavefunction, &
1496 sim_time=qs_env%sim_time)
1497 WRITE (title, *) "WAVEFUNCTION ", ivector, " spin ", ispin, " i.e. HOMO - ", ivector - homo
1498 CALL mo_section%write_pw(wf_r, unit_nr, title, particles=particles, &
1499 stride=section_get_ivals(dft_section, mo_section%concat_to_relative("%STRIDE")), &
1500 max_file_size_mb=section_get_rval(dft_section, "PRINT%MO_CUBES%MAX_FILE_SIZE_MB"), &
1501 mpi_io=mpi_io)
1502 CALL mo_section%print_key_finished_output(unit_nr, logger, input, mo_section%absolute_section_key, mpi_io=mpi_io)
1503 END DO
1504 IF (ASSOCIATED(list_index)) DEALLOCATE (list_index)
1505 END IF
1506
1507 CALL timestop(handle)
1508
1509 END SUBROUTINE qs_scf_post_occ_cubes
1510
1511! **************************************************************************************************
1512!> \brief Computes and prints the Cube Files for MO
1513!> \param input ...
1514!> \param dft_section ...
1515!> \param dft_control ...
1516!> \param logger ...
1517!> \param qs_env the qs_env in which the qs_env lives
1518!> \param unoccupied_orbs ...
1519!> \param wf_g ...
1520!> \param wf_r ...
1521!> \param particles ...
1522!> \param nlumos ...
1523!> \param homo ...
1524!> \param ispin ...
1525!> \param lumo ...
1526!> \param mo_section ...
1527! **************************************************************************************************
1528 SUBROUTINE qs_scf_post_unocc_cubes(input, dft_section, dft_control, logger, qs_env, &
1529 unoccupied_orbs, wf_g, wf_r, particles, nlumos, homo, ispin, lumo, mo_section)
1530
1531 TYPE(section_vals_type), POINTER :: input, dft_section
1532 TYPE(dft_control_type), POINTER :: dft_control
1533 TYPE(cp_logger_type), POINTER :: logger
1534 TYPE(qs_environment_type), POINTER :: qs_env
1535 TYPE(cp_fm_type), INTENT(IN) :: unoccupied_orbs
1536 TYPE(pw_c1d_gs_type), INTENT(INOUT) :: wf_g
1537 TYPE(pw_r3d_rs_type), INTENT(INOUT) :: wf_r
1538 TYPE(particle_list_type), POINTER :: particles
1539 INTEGER, INTENT(IN) :: nlumos, homo, ispin
1540 INTEGER, INTENT(IN), OPTIONAL :: lumo
1541 TYPE(cp_section_key) :: mo_section
1542
1543 CHARACTER(len=*), PARAMETER :: routinen = 'qs_scf_post_unocc_cubes'
1544
1545 CHARACTER(LEN=default_path_length) :: filename, my_pos_cube, title
1546 INTEGER :: handle, ifirst, index_mo, ivector, &
1547 unit_nr
1548 LOGICAL :: append_cube, mpi_io
1549 TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
1550 TYPE(cell_type), POINTER :: cell
1551 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
1552 TYPE(pw_env_type), POINTER :: pw_env
1553 TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
1554
1555 CALL timeset(routinen, handle)
1556
1557#ifndef __OPENPMD
1558 ! Error should usually be caught earlier as PRINT%MO_OPENPMD is not added to the input section
1559 ! if openPMD is not activated
1560 cpassert(mo_section%grid_output /= grid_output_openpmd)
1561#endif
1562
1563 IF (btest(cp_print_key_should_output(logger%iter_info, dft_section, mo_section%relative_section_key), cp_p_file) &
1564 .AND. section_get_lval(dft_section, mo_section%concat_to_relative(section_key_do_write(mo_section%grid_output)))) THEN
1565 NULLIFY (qs_kind_set, particle_set, pw_env, cell)
1566 ! For openPMD, refer to access modes instead of APPEND key
1567 IF (mo_section%grid_output == grid_output_cubes) THEN
1568 append_cube = section_get_lval(dft_section, mo_section%concat_to_relative("%APPEND"))
1569 END IF
1570 my_pos_cube = "REWIND"
1571 IF (append_cube) THEN
1572 my_pos_cube = "APPEND"
1573 END IF
1574 ifirst = 1
1575 IF (PRESENT(lumo)) ifirst = lumo
1576 DO ivector = ifirst, ifirst + nlumos - 1
1577 CALL get_qs_env(qs_env=qs_env, &
1578 atomic_kind_set=atomic_kind_set, &
1579 qs_kind_set=qs_kind_set, &
1580 cell=cell, &
1581 particle_set=particle_set, &
1582 pw_env=pw_env)
1583 CALL calculate_wavefunction(unoccupied_orbs, ivector, wf_r, wf_g, atomic_kind_set, &
1584 qs_kind_set, cell, dft_control, particle_set, pw_env)
1585
1586 IF (ifirst == 1) THEN
1587 index_mo = homo + ivector
1588 ELSE
1589 index_mo = ivector
1590 END IF
1591 WRITE (filename, '(a4,I5.5,a1,I1.1)') "WFN_", index_mo, "_", ispin
1592 mpi_io = .true.
1593
1594 unit_nr = mo_section%print_key_unit_nr( &
1595 logger, &
1596 input, &
1597 mo_section%absolute_section_key, &
1598 extension=".cube", &
1599 middle_name=trim(filename), &
1600 file_position=my_pos_cube, &
1601 log_filename=.false., &
1602 mpi_io=mpi_io, &
1603 openpmd_basename="dft-mo", &
1604 openpmd_unit_dimension=openpmd_unit_dimension_wavefunction, &
1605 openpmd_unit_si=openpmd_unit_si_wavefunction, &
1606 sim_time=qs_env%sim_time)
1607 WRITE (title, *) "WAVEFUNCTION ", index_mo, " spin ", ispin, " i.e. LUMO + ", ifirst + ivector - 2
1608 CALL mo_section%write_pw(wf_r, unit_nr, title, particles=particles, &
1609 stride=section_get_ivals(dft_section, mo_section%concat_to_relative("%STRIDE")), &
1610 max_file_size_mb=section_get_rval(dft_section, "PRINT%MO_CUBES%MAX_FILE_SIZE_MB"), &
1611 mpi_io=mpi_io)
1612 CALL mo_section%print_key_finished_output(unit_nr, logger, input, mo_section%absolute_section_key, mpi_io=mpi_io)
1613
1614 END DO
1615 END IF
1616
1617 CALL timestop(handle)
1618
1619 END SUBROUTINE qs_scf_post_unocc_cubes
1620
1621! **************************************************************************************************
1622!> \brief Computes and prints electric moments
1623!> \param input ...
1624!> \param logger ...
1625!> \param qs_env the qs_env in which the qs_env lives
1626!> \param output_unit ...
1627! **************************************************************************************************
1628 SUBROUTINE qs_scf_post_moments(input, logger, qs_env, output_unit)
1629 TYPE(section_vals_type), POINTER :: input
1630 TYPE(cp_logger_type), POINTER :: logger
1631 TYPE(qs_environment_type), POINTER :: qs_env
1632 INTEGER, INTENT(IN) :: output_unit
1633
1634 CHARACTER(len=*), PARAMETER :: routinen = 'qs_scf_post_moments'
1635
1636 CHARACTER(LEN=default_path_length) :: filename
1637 INTEGER :: handle, max_nmo, maxmom, moments_format, &
1638 moments_unit_nr, reference, unit_nr
1639 LOGICAL :: com_nl, do_kg, do_kpoints, magnetic, &
1640 new_file, periodic, second_ref_point, &
1641 vel_reprs
1642 REAL(kind=dp), DIMENSION(:), POINTER :: ref_point
1643 TYPE(section_vals_type), POINTER :: print_key
1644
1645 CALL timeset(routinen, handle)
1646
1647 print_key => section_vals_get_subs_vals(section_vals=input, &
1648 subsection_name="DFT%PRINT%MOMENTS")
1649
1650 IF (btest(cp_print_key_should_output(logger%iter_info, print_key), cp_p_file)) THEN
1651
1652 maxmom = section_get_ival(section_vals=input, &
1653 keyword_name="DFT%PRINT%MOMENTS%MAX_MOMENT")
1654 moments_format = section_get_ival(section_vals=input, &
1655 keyword_name="DFT%PRINT%MOMENTS%FORMAT")
1656 periodic = section_get_lval(section_vals=input, &
1657 keyword_name="DFT%PRINT%MOMENTS%PERIODIC")
1658 reference = section_get_ival(section_vals=input, &
1659 keyword_name="DFT%PRINT%MOMENTS%REFERENCE")
1660 magnetic = section_get_lval(section_vals=input, &
1661 keyword_name="DFT%PRINT%MOMENTS%MAGNETIC")
1662 vel_reprs = section_get_lval(section_vals=input, &
1663 keyword_name="DFT%PRINT%MOMENTS%VEL_REPRS")
1664 com_nl = section_get_lval(section_vals=input, &
1665 keyword_name="DFT%PRINT%MOMENTS%COM_NL")
1666 second_ref_point = section_get_lval(section_vals=input, &
1667 keyword_name="DFT%PRINT%MOMENTS%SECOND_REFERENCE_POINT")
1668 do_kg = section_get_lval(section_vals=input, &
1669 keyword_name="DFT%PRINT%MOMENTS%KG")
1670 max_nmo = section_get_ival(section_vals=input, &
1671 keyword_name="DFT%PRINT%MOMENTS%MAX_NMO")
1672
1673 NULLIFY (ref_point)
1674 CALL section_vals_val_get(input, "DFT%PRINT%MOMENTS%REF_POINT", r_vals=ref_point)
1675 unit_nr = cp_print_key_unit_nr(logger=logger, basis_section=input, &
1676 print_key_path="DFT%PRINT%MOMENTS", extension=".dat", &
1677 middle_name="moments", log_filename=.false., &
1678 is_new_file=new_file)
1679
1680 IF (output_unit > 0) THEN
1681 IF (unit_nr /= output_unit) THEN
1682 INQUIRE (unit=unit_nr, name=filename)
1683 WRITE (unit=output_unit, fmt="(/,T2,A,2(/,T3,A),/)") &
1684 "MOMENTS", "The electric/magnetic moments are written to file:", &
1685 trim(filename)
1686 ELSE IF (moments_format /= moments_format_trajectory) THEN
1687 WRITE (unit=output_unit, fmt="(/,T2,A)") "ELECTRIC/MAGNETIC MOMENTS"
1688 END IF
1689 END IF
1690
1691 CALL get_qs_env(qs_env, do_kpoints=do_kpoints)
1692
1693 IF (moments_format == moments_format_trajectory) THEN
1694 IF (do_kpoints) THEN
1695 cpabort("MOMENTS FORMAT TRAJECTORY is not available for k-point calculations.")
1696 END IF
1697 IF (maxmom /= 1) cpabort("MOMENTS FORMAT TRAJECTORY requires MAX_MOMENT 1.")
1698 IF (magnetic) cpabort("MOMENTS FORMAT TRAJECTORY does not support MAGNETIC moments.")
1699 IF (vel_reprs) cpabort("MOMENTS FORMAT TRAJECTORY does not support VEL_REPRS.")
1700 IF (do_kg) cpabort("MOMENTS FORMAT TRAJECTORY does not support KG moments.")
1701 moments_unit_nr = -1
1702 ELSE
1703 moments_unit_nr = unit_nr
1704 END IF
1705
1706 IF (do_kpoints) THEN
1707 CALL qs_moment_kpoints(qs_env, maxmom, reference, ref_point, max_nmo, moments_unit_nr)
1708 ELSE
1709 IF (periodic) THEN
1710 CALL qs_moment_berry_phase(qs_env, magnetic, maxmom, reference, ref_point, moments_unit_nr)
1711 ELSE
1712 CALL qs_moment_locop(qs_env, magnetic, maxmom, reference, ref_point, moments_unit_nr, vel_reprs, com_nl)
1713 END IF
1714 IF (do_kg) THEN
1715 CALL calculate_kg_moments(qs_env, moments_unit_nr, maxmom, magnetic, vel_reprs, com_nl)
1716 END IF
1717 END IF
1718 IF (moments_format == moments_format_trajectory) THEN
1719 CALL write_moments_trajectory(unit_nr, logger, qs_env, periodic, new_file, "MOMENTS|")
1720 END IF
1721
1722 CALL cp_print_key_finished_output(unit_nr=unit_nr, logger=logger, &
1723 basis_section=input, print_key_path="DFT%PRINT%MOMENTS")
1724
1725 IF (second_ref_point) THEN
1726 reference = section_get_ival(section_vals=input, &
1727 keyword_name="DFT%PRINT%MOMENTS%REFERENCE_2")
1728
1729 NULLIFY (ref_point)
1730 CALL section_vals_val_get(input, "DFT%PRINT%MOMENTS%REF_POINT_2", r_vals=ref_point)
1731 unit_nr = cp_print_key_unit_nr(logger=logger, basis_section=input, &
1732 print_key_path="DFT%PRINT%MOMENTS", extension=".dat", &
1733 middle_name="moments_refpoint_2", log_filename=.false., &
1734 is_new_file=new_file)
1735
1736 IF (output_unit > 0) THEN
1737 IF (unit_nr /= output_unit) THEN
1738 INQUIRE (unit=unit_nr, name=filename)
1739 WRITE (unit=output_unit, fmt="(/,T2,A,2(/,T3,A),/)") &
1740 "MOMENTS", "The electric/magnetic moments for the second reference point are written to file:", &
1741 trim(filename)
1742 ELSE IF (moments_format /= moments_format_trajectory) THEN
1743 WRITE (unit=output_unit, fmt="(/,T2,A)") "ELECTRIC/MAGNETIC MOMENTS"
1744 END IF
1745 END IF
1746 IF (moments_format /= moments_format_trajectory) moments_unit_nr = unit_nr
1747 IF (do_kpoints) THEN
1748 CALL qs_moment_kpoints(qs_env, maxmom, reference, ref_point, max_nmo, moments_unit_nr)
1749 ELSE
1750 IF (periodic) THEN
1751 CALL qs_moment_berry_phase(qs_env, magnetic, maxmom, reference, ref_point, moments_unit_nr)
1752 ELSE
1753 CALL qs_moment_locop(qs_env, magnetic, maxmom, reference, ref_point, &
1754 moments_unit_nr, vel_reprs, com_nl)
1755 END IF
1756 END IF
1757 IF (moments_format == moments_format_trajectory) THEN
1758 CALL write_moments_trajectory(unit_nr, logger, qs_env, periodic, new_file, "MOMENTS_REF2|")
1759 END IF
1760 CALL cp_print_key_finished_output(unit_nr=unit_nr, logger=logger, &
1761 basis_section=input, print_key_path="DFT%PRINT%MOMENTS")
1762 END IF
1763
1764 END IF
1765
1766 CALL timestop(handle)
1767
1768 END SUBROUTINE qs_scf_post_moments
1769
1770! **************************************************************************************************
1771!> \brief Writes one machine-readable electric-dipole record for the current iteration.
1772!> \param unit_nr output unit
1773!> \param logger logger carrying the current iteration levels
1774!> \param qs_env quantum environment containing the dipole result and cell
1775!> \param periodic whether the Berry-phase operator was used
1776!> \param new_file whether the output file has just been created
1777!> \param label record label
1778! **************************************************************************************************
1779 SUBROUTINE write_moments_trajectory(unit_nr, logger, qs_env, periodic, new_file, label)
1780 INTEGER, INTENT(IN) :: unit_nr
1781 TYPE(cp_logger_type), POINTER :: logger
1782 TYPE(qs_environment_type), POINTER :: qs_env
1783 LOGICAL, INTENT(IN) :: periodic, new_file
1784 CHARACTER(LEN=*), INTENT(IN) :: label
1785
1786 CHARACTER(LEN=default_string_length) :: description, iter
1787 REAL(kind=dp), DIMENSION(3) :: dipole
1788 TYPE(cell_type), POINTER :: cell
1789 TYPE(cp_result_type), POINTER :: results
1790
1791 IF (unit_nr <= 0) RETURN
1792
1793 NULLIFY (cell, results)
1794 CALL get_qs_env(qs_env, cell=cell, results=results)
1795 description = "[DIPOLE]"
1796 CALL get_results(results=results, description=description, values=dipole)
1797
1798 IF (new_file) THEN
1799 IF (periodic) THEN
1800 WRITE (unit_nr, "(A)") "# "//trim(label)// &
1801 " iter_level dipole_x dipole_y dipole_z dipole_norm cell_xx cell_xy cell_xz"// &
1802 " cell_yx cell_yy cell_yz cell_zx cell_zy cell_zz [Debye]"
1803 ELSE
1804 WRITE (unit_nr, "(A)") "# "//trim(label)// &
1805 " iter_level dipole_x dipole_y dipole_z dipole_norm [Debye]"
1806 END IF
1807 END IF
1808
1809 iter = cp_iter_string(logger%iter_info)
1810 IF (periodic) THEN
1811 WRITE (unit_nr, "(1X,A,1X,A15,13(1X,ES18.10))") trim(label), iter(1:15), &
1812 dipole*debye, sqrt(sum(dipole**2))*debye, &
1813 cell%hmat(1, :)*debye, cell%hmat(2, :)*debye, cell%hmat(3, :)*debye
1814 ELSE
1815 WRITE (unit_nr, "(1X,A,1X,A15,4(1X,ES18.10))") trim(label), iter(1:15), &
1816 dipole*debye, sqrt(sum(dipole**2))*debye
1817 END IF
1818
1819 END SUBROUTINE write_moments_trajectory
1820
1821! **************************************************************************************************
1822!> \brief Computes and prints the X-ray diffraction spectrum.
1823!> \param input ...
1824!> \param dft_section ...
1825!> \param logger ...
1826!> \param qs_env the qs_env in which the qs_env lives
1827!> \param output_unit ...
1828! **************************************************************************************************
1829 SUBROUTINE qs_scf_post_xray(input, dft_section, logger, qs_env, output_unit)
1830
1831 TYPE(section_vals_type), POINTER :: input, dft_section
1832 TYPE(cp_logger_type), POINTER :: logger
1833 TYPE(qs_environment_type), POINTER :: qs_env
1834 INTEGER, INTENT(IN) :: output_unit
1835
1836 CHARACTER(LEN=*), PARAMETER :: routinen = 'qs_scf_post_xray'
1837
1838 CHARACTER(LEN=default_path_length) :: filename
1839 INTEGER :: handle, unit_nr
1840 REAL(kind=dp) :: q_max
1841 TYPE(section_vals_type), POINTER :: print_key
1842
1843 CALL timeset(routinen, handle)
1844
1845 print_key => section_vals_get_subs_vals(section_vals=input, &
1846 subsection_name="DFT%PRINT%XRAY_DIFFRACTION_SPECTRUM")
1847
1848 IF (btest(cp_print_key_should_output(logger%iter_info, print_key), cp_p_file)) THEN
1849 q_max = section_get_rval(section_vals=dft_section, &
1850 keyword_name="PRINT%XRAY_DIFFRACTION_SPECTRUM%Q_MAX")
1851 unit_nr = cp_print_key_unit_nr(logger=logger, &
1852 basis_section=input, &
1853 print_key_path="DFT%PRINT%XRAY_DIFFRACTION_SPECTRUM", &
1854 extension=".dat", &
1855 middle_name="xrd", &
1856 log_filename=.false.)
1857 IF (output_unit > 0) THEN
1858 INQUIRE (unit=unit_nr, name=filename)
1859 WRITE (unit=output_unit, fmt="(/,/,T2,A)") &
1860 "X-RAY DIFFRACTION SPECTRUM"
1861 IF (unit_nr /= output_unit) THEN
1862 WRITE (unit=output_unit, fmt="(/,T3,A,/,/,T3,A,/)") &
1863 "The coherent X-ray diffraction spectrum is written to the file:", &
1864 trim(filename)
1865 END IF
1866 END IF
1867 CALL xray_diffraction_spectrum(qs_env=qs_env, &
1868 unit_number=unit_nr, &
1869 q_max=q_max)
1870 CALL cp_print_key_finished_output(unit_nr=unit_nr, &
1871 logger=logger, &
1872 basis_section=input, &
1873 print_key_path="DFT%PRINT%XRAY_DIFFRACTION_SPECTRUM")
1874 END IF
1875
1876 CALL timestop(handle)
1877
1878 END SUBROUTINE qs_scf_post_xray
1879
1880! **************************************************************************************************
1881!> \brief Computes and prints Electric Field Gradient
1882!> \param input ...
1883!> \param logger ...
1884!> \param qs_env the qs_env in which the qs_env lives
1885! **************************************************************************************************
1886 SUBROUTINE qs_scf_post_efg(input, logger, qs_env)
1887 TYPE(section_vals_type), POINTER :: input
1888 TYPE(cp_logger_type), POINTER :: logger
1889 TYPE(qs_environment_type), POINTER :: qs_env
1890
1891 CHARACTER(len=*), PARAMETER :: routinen = 'qs_scf_post_efg'
1892
1893 INTEGER :: handle
1894 TYPE(section_vals_type), POINTER :: print_key
1895
1896 CALL timeset(routinen, handle)
1897
1898 print_key => section_vals_get_subs_vals(section_vals=input, &
1899 subsection_name="DFT%PRINT%ELECTRIC_FIELD_GRADIENT")
1900 IF (btest(cp_print_key_should_output(logger%iter_info, print_key), &
1901 cp_p_file)) THEN
1902 CALL qs_efg_calc(qs_env=qs_env)
1903 END IF
1904
1905 CALL timestop(handle)
1906
1907 END SUBROUTINE qs_scf_post_efg
1908
1909! **************************************************************************************************
1910!> \brief Computes the Electron Transfer Coupling matrix element
1911!> \param input ...
1912!> \param qs_env the qs_env in which the qs_env lives
1913!> \param dft_control ...
1914! **************************************************************************************************
1915 SUBROUTINE qs_scf_post_et(input, qs_env, dft_control)
1916 TYPE(section_vals_type), POINTER :: input
1917 TYPE(qs_environment_type), POINTER :: qs_env
1918 TYPE(dft_control_type), POINTER :: dft_control
1919
1920 CHARACTER(len=*), PARAMETER :: routinen = 'qs_scf_post_et'
1921
1922 INTEGER :: handle, ispin
1923 LOGICAL :: do_et
1924 TYPE(cp_fm_type), DIMENSION(:), POINTER :: my_mos
1925 TYPE(section_vals_type), POINTER :: et_section
1926
1927 CALL timeset(routinen, handle)
1928
1929 do_et = .false.
1930 et_section => section_vals_get_subs_vals(input, "PROPERTIES%ET_COUPLING")
1931 CALL section_vals_get(et_section, explicit=do_et)
1932 IF (do_et) THEN
1933 IF (qs_env%et_coupling%first_run) THEN
1934 NULLIFY (my_mos)
1935 ALLOCATE (my_mos(dft_control%nspins))
1936 ALLOCATE (qs_env%et_coupling%et_mo_coeff(dft_control%nspins))
1937 DO ispin = 1, dft_control%nspins
1938 CALL cp_fm_create(matrix=my_mos(ispin), &
1939 matrix_struct=qs_env%mos(ispin)%mo_coeff%matrix_struct, &
1940 name="FIRST_RUN_COEFF"//trim(adjustl(cp_to_string(ispin)))//"MATRIX")
1941 CALL cp_fm_to_fm(qs_env%mos(ispin)%mo_coeff, &
1942 my_mos(ispin))
1943 END DO
1944 CALL set_et_coupling_type(qs_env%et_coupling, et_mo_coeff=my_mos)
1945 DEALLOCATE (my_mos)
1946 END IF
1947 END IF
1948
1949 CALL timestop(handle)
1950
1951 END SUBROUTINE qs_scf_post_et
1952
1953! **************************************************************************************************
1954!> \brief compute the electron localization function
1955!>
1956!> \param input ...
1957!> \param logger ...
1958!> \param qs_env ...
1959!> \par History
1960!> 2012-07 Created [MI]
1961! **************************************************************************************************
1962 SUBROUTINE qs_scf_post_elf(input, logger, qs_env)
1963 TYPE(section_vals_type), POINTER :: input
1964 TYPE(cp_logger_type), POINTER :: logger
1965 TYPE(qs_environment_type), POINTER :: qs_env
1966
1967 CHARACTER(len=*), PARAMETER :: routinen = 'qs_scf_post_elf'
1968
1969 CHARACTER(LEN=default_path_length) :: filename, mpi_filename, my_pos_cube, &
1970 title
1971 INTEGER :: handle, ispin, output_unit, unit_nr
1972 LOGICAL :: append_cube, gapw, mpi_io
1973 REAL(dp) :: rho_cutoff
1974 TYPE(cp_section_key) :: elf_section_key
1975 TYPE(dft_control_type), POINTER :: dft_control
1976 TYPE(particle_list_type), POINTER :: particles
1977 TYPE(pw_env_type), POINTER :: pw_env
1978 TYPE(pw_pool_p_type), DIMENSION(:), POINTER :: pw_pools
1979 TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
1980 TYPE(pw_r3d_rs_type), ALLOCATABLE, DIMENSION(:) :: elf_r
1981 TYPE(qs_subsys_type), POINTER :: subsys
1982 TYPE(section_vals_type), POINTER :: elf_section
1983
1984 CALL timeset(routinen, handle)
1985 output_unit = cp_logger_get_default_io_unit(logger)
1986
1987 elf_section_key = cube_or_openpmd(input, str_elf_cubes, str_elf_openpmd, logger)
1988
1989 elf_section => section_vals_get_subs_vals(input, elf_section_key%absolute_section_key)
1990 IF (elf_section_key%do_output) THEN
1991
1992 NULLIFY (dft_control, pw_env, auxbas_pw_pool, pw_pools, particles, subsys)
1993 CALL get_qs_env(qs_env, dft_control=dft_control, pw_env=pw_env, subsys=subsys)
1994 CALL qs_subsys_get(subsys, particles=particles)
1995
1996 gapw = dft_control%qs_control%gapw
1997 IF (.NOT. gapw) THEN
1998 ! allocate
1999 ALLOCATE (elf_r(dft_control%nspins))
2000 CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool, &
2001 pw_pools=pw_pools)
2002 DO ispin = 1, dft_control%nspins
2003 CALL auxbas_pw_pool%create_pw(elf_r(ispin))
2004 CALL pw_zero(elf_r(ispin))
2005 END DO
2006
2007 IF (output_unit > 0) THEN
2008 WRITE (unit=output_unit, fmt="(/,T15,A,/)") &
2009 " ----- ELF is computed on the real space grid -----"
2010 END IF
2011 rho_cutoff = section_get_rval(elf_section, "density_cutoff")
2012 CALL qs_elf_calc(qs_env, elf_r, rho_cutoff)
2013
2014 ! write ELF into cube file
2015
2016 ! For openPMD, refer to access modes instead of APPEND key
2017 IF (elf_section_key%grid_output == grid_output_cubes) THEN
2018 append_cube = section_get_lval(elf_section, "APPEND")
2019 END IF
2020 my_pos_cube = "REWIND"
2021 IF (append_cube) THEN
2022 my_pos_cube = "APPEND"
2023 END IF
2024
2025 DO ispin = 1, dft_control%nspins
2026 WRITE (filename, '(a5,I1.1)') "ELF_S", ispin
2027 WRITE (title, *) "ELF spin ", ispin
2028 mpi_io = .true.
2029 unit_nr = elf_section_key%print_key_unit_nr( &
2030 logger, &
2031 input, &
2032 elf_section_key%absolute_section_key, &
2033 extension=".cube", &
2034 middle_name=trim(filename), &
2035 file_position=my_pos_cube, &
2036 log_filename=.false., &
2037 mpi_io=mpi_io, &
2038 fout=mpi_filename, &
2039 openpmd_basename="dft-elf", &
2040 openpmd_unit_dimension=openpmd_unit_dimension_dimensionless, &
2041 openpmd_unit_si=openpmd_unit_si_dimensionless, &
2042 sim_time=qs_env%sim_time)
2043 IF (output_unit > 0) THEN
2044 IF (.NOT. mpi_io) THEN
2045 INQUIRE (unit=unit_nr, name=filename)
2046 ELSE
2047 filename = mpi_filename
2048 END IF
2049 WRITE (unit=output_unit, fmt="(/,T2,A,/,/,T2,A)") &
2050 "ELF is written in "//elf_section_key%format_name//" file format to the file:", &
2051 trim(filename)
2052 END IF
2053
2054 CALL elf_section_key%write_pw(elf_r(ispin), unit_nr, title, particles=particles, &
2055 stride=section_get_ivals(elf_section, "STRIDE"), mpi_io=mpi_io)
2056 CALL elf_section_key%print_key_finished_output( &
2057 unit_nr, &
2058 logger, &
2059 input, &
2060 elf_section_key%absolute_section_key, &
2061 mpi_io=mpi_io)
2062
2063 CALL auxbas_pw_pool%give_back_pw(elf_r(ispin))
2064 END DO
2065
2066 ! deallocate
2067 DEALLOCATE (elf_r)
2068
2069 ELSE
2070 ! not implemented
2071 cpwarn("ELF not implemented for GAPW calculations!")
2072 END IF
2073
2074 END IF ! print key
2075
2076 CALL timestop(handle)
2077
2078 END SUBROUTINE qs_scf_post_elf
2079
2080! **************************************************************************************************
2081!> \brief computes the condition number of the overlap matrix and
2082!> prints the value of the total energy. This is needed
2083!> for BASIS_MOLOPT optimizations
2084!> \param input ...
2085!> \param logger ...
2086!> \param qs_env the qs_env in which the qs_env lives
2087!> \par History
2088!> 2007-07 Created [Joost VandeVondele]
2089! **************************************************************************************************
2090 SUBROUTINE qs_scf_post_molopt(input, logger, qs_env)
2091 TYPE(section_vals_type), POINTER :: input
2092 TYPE(cp_logger_type), POINTER :: logger
2093 TYPE(qs_environment_type), POINTER :: qs_env
2094
2095 CHARACTER(len=*), PARAMETER :: routinen = 'qs_scf_post_molopt'
2096
2097 INTEGER :: handle, nao, unit_nr
2098 REAL(kind=dp) :: s_cond_number
2099 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: eigenvalues
2100 TYPE(cp_fm_struct_type), POINTER :: ao_ao_fmstruct
2101 TYPE(cp_fm_type) :: fm_s, fm_work
2102 TYPE(cp_fm_type), POINTER :: mo_coeff
2103 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_s
2104 TYPE(mo_set_type), DIMENSION(:), POINTER :: mos
2105 TYPE(qs_energy_type), POINTER :: energy
2106 TYPE(section_vals_type), POINTER :: print_key
2107
2108 CALL timeset(routinen, handle)
2109
2110 print_key => section_vals_get_subs_vals(section_vals=input, &
2111 subsection_name="DFT%PRINT%BASIS_MOLOPT_QUANTITIES")
2112 IF (btest(cp_print_key_should_output(logger%iter_info, print_key), &
2113 cp_p_file)) THEN
2114
2115 CALL get_qs_env(qs_env, energy=energy, matrix_s=matrix_s, mos=mos)
2116
2117 ! set up the two needed full matrices, using mo_coeff as a template
2118 CALL get_mo_set(mo_set=mos(1), mo_coeff=mo_coeff, nao=nao)
2119 CALL cp_fm_struct_create(fmstruct=ao_ao_fmstruct, &
2120 nrow_global=nao, ncol_global=nao, &
2121 template_fmstruct=mo_coeff%matrix_struct)
2122 CALL cp_fm_create(fm_s, matrix_struct=ao_ao_fmstruct, &
2123 name="fm_s")
2124 CALL cp_fm_create(fm_work, matrix_struct=ao_ao_fmstruct, &
2125 name="fm_work")
2126 CALL cp_fm_struct_release(ao_ao_fmstruct)
2127 ALLOCATE (eigenvalues(nao))
2128
2129 CALL copy_dbcsr_to_fm(matrix_s(1)%matrix, fm_s)
2130 CALL choose_eigv_solver(fm_s, fm_work, eigenvalues)
2131
2132 CALL cp_fm_release(fm_s)
2133 CALL cp_fm_release(fm_work)
2134
2135 s_cond_number = maxval(abs(eigenvalues))/max(minval(abs(eigenvalues)), epsilon(0.0_dp))
2136
2137 unit_nr = cp_print_key_unit_nr(logger, input, "DFT%PRINT%BASIS_MOLOPT_QUANTITIES", &
2138 extension=".molopt")
2139
2140 IF (unit_nr > 0) THEN
2141 ! please keep this format fixed, needs to be grepable for molopt
2142 ! optimizations
2143 WRITE (unit_nr, '(T2,A28,2A25)') "", "Tot. Ener.", "S Cond. Numb."
2144 WRITE (unit_nr, '(T2,A28,2E25.17)') "BASIS_MOLOPT_QUANTITIES", energy%total, s_cond_number
2145 END IF
2146
2147 CALL cp_print_key_finished_output(unit_nr, logger, input, &
2148 "DFT%PRINT%BASIS_MOLOPT_QUANTITIES")
2149
2150 END IF
2151
2152 CALL timestop(handle)
2153
2154 END SUBROUTINE qs_scf_post_molopt
2155
2156! **************************************************************************************************
2157!> \brief Dumps EPR
2158!> \param input ...
2159!> \param logger ...
2160!> \param qs_env the qs_env in which the qs_env lives
2161! **************************************************************************************************
2162 SUBROUTINE qs_scf_post_epr(input, logger, qs_env)
2163 TYPE(section_vals_type), POINTER :: input
2164 TYPE(cp_logger_type), POINTER :: logger
2165 TYPE(qs_environment_type), POINTER :: qs_env
2166
2167 CHARACTER(len=*), PARAMETER :: routinen = 'qs_scf_post_epr'
2168
2169 INTEGER :: handle
2170 TYPE(section_vals_type), POINTER :: print_key
2171
2172 CALL timeset(routinen, handle)
2173
2174 print_key => section_vals_get_subs_vals(section_vals=input, &
2175 subsection_name="DFT%PRINT%HYPERFINE_COUPLING_TENSOR")
2176 IF (btest(cp_print_key_should_output(logger%iter_info, print_key), &
2177 cp_p_file)) THEN
2178 CALL qs_epr_hyp_calc(qs_env=qs_env)
2179 END IF
2180
2181 CALL timestop(handle)
2182
2183 END SUBROUTINE qs_scf_post_epr
2184
2185! **************************************************************************************************
2186!> \brief Interface routine to trigger writing of results available from normal
2187!> SCF. Can write MO-dependent and MO free results (needed for call from
2188!> the linear scaling code)
2189!> \param qs_env the qs_env in which the qs_env lives
2190!> \param scf_env ...
2191! **************************************************************************************************
2192 SUBROUTINE write_available_results(qs_env, scf_env)
2193 TYPE(qs_environment_type), POINTER :: qs_env
2194 TYPE(qs_scf_env_type), OPTIONAL, POINTER :: scf_env
2195
2196 CHARACTER(len=*), PARAMETER :: routinen = 'write_available_results'
2197
2198 INTEGER :: handle
2199
2200 CALL timeset(routinen, handle)
2201
2202 ! those properties that require MOs (not suitable density matrix based methods)
2203 CALL write_mo_dependent_results(qs_env, scf_env)
2204
2205 ! those that depend only on the density matrix, they should be linear scaling in their implementation
2206 CALL write_mo_free_results(qs_env)
2207
2208 CALL timestop(handle)
2209
2210 END SUBROUTINE write_available_results
2211
2212! **************************************************************************************************
2213!> \brief Write QS results available if MO's are present (if switched on through the print_keys)
2214!> Writes only MO dependent results. Split is necessary as ls_scf does not
2215!> provide MO's
2216!> \param qs_env the qs_env in which the qs_env lives
2217!> \param scf_env ...
2218! **************************************************************************************************
2219 SUBROUTINE write_mo_dependent_results(qs_env, scf_env)
2220 TYPE(qs_environment_type), POINTER :: qs_env
2221 TYPE(qs_scf_env_type), OPTIONAL, POINTER :: scf_env
2222
2223 CHARACTER(len=*), PARAMETER :: routinen = 'write_mo_dependent_results'
2224
2225 INTEGER :: handle, homo, ispin, nlumo_dos, &
2226 nlumo_molden, nlumo_required, nlumos, &
2227 nmo, output_unit
2228 LOGICAL :: all_equal, defer_molden, do_curve, &
2229 do_dos, do_kpoints, do_pdos, &
2230 do_projected_dos, explicit
2231 REAL(kind=dp) :: maxocc, s_square, s_square_ideal, &
2232 total_abs_spin_dens, total_spin_dens
2233 REAL(kind=dp), DIMENSION(:), POINTER :: mo_eigenvalues, occupation_numbers
2234 TYPE(admm_type), POINTER :: admm_env
2235 TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
2236 TYPE(cell_type), POINTER :: cell
2237 TYPE(cp_1d_r_p_type), DIMENSION(:), POINTER :: unoccupied_evals
2238 TYPE(cp_fm_type), DIMENSION(:), POINTER :: unoccupied_orbs
2239 TYPE(cp_fm_type), POINTER :: mo_coeff
2240 TYPE(cp_logger_type), POINTER :: logger
2241 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: ks_rmpv, matrix_s
2242 TYPE(dbcsr_type), POINTER :: mo_coeff_deriv
2243 TYPE(dft_control_type), POINTER :: dft_control
2244 TYPE(mo_set_type), DIMENSION(:), POINTER :: mos
2245 TYPE(molecule_type), POINTER :: molecule_set(:)
2246 TYPE(particle_list_type), POINTER :: particles
2247 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
2248 TYPE(pw_env_type), POINTER :: pw_env
2249 TYPE(pw_pool_p_type), DIMENSION(:), POINTER :: pw_pools
2250 TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
2251 TYPE(pw_r3d_rs_type) :: wf_r
2252 TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: rho_r
2253 TYPE(qs_charges_type), POINTER :: qs_charges
2254 TYPE(qs_energy_type), POINTER :: energy
2255 TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
2256 TYPE(qs_rho_type), POINTER :: rho
2257 TYPE(qs_subsys_type), POINTER :: subsys
2258 TYPE(scf_control_type), POINTER :: scf_control
2259 TYPE(section_vals_type), POINTER :: casino_section, dft_section, &
2260 dos_section, input, sprint_section, &
2261 trexio_section
2262
2263! TYPE(kpoint_type), POINTER :: kpoints
2264
2265 CALL timeset(routinen, handle)
2266
2267 NULLIFY (cell, dft_control, pw_env, auxbas_pw_pool, pw_pools, mo_coeff, &
2268 mo_coeff_deriv, mo_eigenvalues, mos, atomic_kind_set, qs_kind_set, &
2269 particle_set, rho, ks_rmpv, matrix_s, scf_control, dft_section, &
2270 molecule_set, input, particles, subsys, rho_r, unoccupied_orbs, &
2271 unoccupied_evals, casino_section, dos_section)
2272
2273 logger => cp_get_default_logger()
2274 output_unit = cp_logger_get_default_io_unit(logger)
2275
2276 cpassert(ASSOCIATED(qs_env))
2277 CALL get_qs_env(qs_env, &
2278 dft_control=dft_control, &
2279 molecule_set=molecule_set, &
2280 atomic_kind_set=atomic_kind_set, &
2281 particle_set=particle_set, &
2282 qs_kind_set=qs_kind_set, &
2283 admm_env=admm_env, &
2284 scf_control=scf_control, &
2285 input=input, &
2286 cell=cell, &
2287 subsys=subsys)
2288 CALL qs_subsys_get(subsys, particles=particles)
2289 CALL get_qs_env(qs_env, rho=rho)
2290 CALL qs_rho_get(rho, rho_r=rho_r)
2291
2292 ! k points
2293 CALL get_qs_env(qs_env, do_kpoints=do_kpoints)
2294
2295 ! Write last MO information to output file if requested
2296 dft_section => section_vals_get_subs_vals(input, "DFT")
2297 IF (.NOT. qs_env%run_rtp) THEN
2298 CALL qs_scf_write_mos(qs_env, scf_env, final_mos=.true.)
2299 trexio_section => section_vals_get_subs_vals(dft_section, "PRINT%TREXIO")
2300 CALL section_vals_get(trexio_section, explicit=explicit)
2301 IF (explicit) THEN
2302 CALL write_trexio(qs_env, trexio_section)
2303 END IF
2304 casino_section => section_vals_get_subs_vals(dft_section, "PRINT%CASINO")
2305 CALL section_vals_get(casino_section, explicit=explicit)
2306 IF (explicit) THEN
2307 CALL write_casino(qs_env, casino_section)
2308 END IF
2309 sprint_section => section_vals_get_subs_vals(dft_section, "PRINT%MO_MOLDEN")
2310 defer_molden = .false.
2311 IF (.NOT. do_kpoints) THEN
2312 CALL get_qs_env(qs_env, mos=mos, matrix_ks=ks_rmpv)
2313 CALL write_dm_binary_restart(mos, dft_section, ks_rmpv)
2314 ! Check if molden write should be deferred for OT unoccupied orbitals
2315 CALL section_vals_val_get(sprint_section, "NLUMO", i_val=nlumo_molden)
2316 IF (nlumo_molden /= 0 .AND. PRESENT(scf_env)) THEN
2317 IF (scf_env%method == ot_method_nr) defer_molden = .true.
2318 END IF
2319 IF (.NOT. defer_molden) THEN
2320 CALL write_mos_molden(mos, qs_kind_set, particle_set, sprint_section, cell=cell, &
2321 qs_env=qs_env, calc_energies=.true.)
2322 END IF
2323 ! Write Chargemol .wfx
2324 IF (btest(cp_print_key_should_output(logger%iter_info, dft_section, "PRINT%CHARGEMOL"), &
2325 cp_p_file)) THEN
2326 CALL write_wfx(qs_env, dft_section)
2327 END IF
2328 ELSE
2329 IF (btest(cp_print_key_should_output(logger%iter_info, sprint_section, ""), cp_p_file)) THEN
2330 cpwarn("Molden format output is not possible for k-point calculations.")
2331 END IF
2332 IF (btest(cp_print_key_should_output(logger%iter_info, dft_section, "PRINT%CHARGEMOL"), &
2333 cp_p_file)) THEN
2334 cpwarn("Chargemol .wfx format output is not possible for k-point calculations.")
2335 END IF
2336 END IF
2337
2338 ! K-point MO wavefunction dump
2339 IF (btest(cp_print_key_should_output(logger%iter_info, dft_section, "PRINT%MO_KP"), &
2340 cp_p_file)) THEN
2341 IF (do_kpoints) THEN
2342 CALL write_kpoint_mo_data(qs_env, &
2343 section_vals_get_subs_vals(input, "DFT%PRINT%MO_KP"))
2344 ELSE
2345 cpwarn("MO_KP is only available for k-point calculations, ignored for Gamma-only")
2346 END IF
2347 END IF
2348
2349 dos_section => section_vals_get_subs_vals(dft_section, "PRINT%DOS")
2350 do_dos = btest(cp_print_key_should_output(logger%iter_info, dos_section), cp_p_file)
2351 CALL get_dos_pdos_flags(dos_section, do_dos, do_projected_dos, do_pdos, do_curve)
2352
2353 ! For OT calculations, collect the largest request for additional unoccupied
2354 ! orbitals among DOS, PDOS, and Molden, and generate them only once.
2355 nlumo_required = 0
2356 IF (.NOT. do_kpoints .AND. PRESENT(scf_env)) THEN
2357 IF (scf_env%method == ot_method_nr) THEN
2358 IF (do_dos) THEN
2359 CALL section_vals_val_get(dft_section, "PRINT%DOS%NLUMO", i_val=nlumo_dos)
2360 IF (nlumo_dos == -1) THEN
2361 nlumo_required = -1
2362 ELSE IF (nlumo_required /= -1) THEN
2363 nlumo_required = max(nlumo_required, nlumo_dos)
2364 END IF
2365 END IF
2366
2367 IF (defer_molden) THEN
2368 IF (nlumo_molden == -1) THEN
2369 nlumo_required = -1
2370 ELSE IF (nlumo_required /= -1) THEN
2371 nlumo_required = max(nlumo_required, nlumo_molden)
2372 END IF
2373 END IF
2374 IF (nlumo_required /= 0) THEN
2375 ALLOCATE (unoccupied_orbs(dft_control%nspins))
2376 ALLOCATE (unoccupied_evals(dft_control%nspins))
2377 CALL make_lumo_gpw(qs_env, scf_env, unoccupied_orbs, unoccupied_evals, &
2378 nlumo_required, nlumos)
2379 END IF
2380
2381 IF (do_dos .OR. do_projected_dos) THEN
2382 DO ispin = 1, dft_control%nspins
2383 ! With ADMM, temporarily modify the Kohn-Sham matrix while updating the
2384 ! eigenvalues and rotating the occupied OT subspace.
2385 IF (dft_control%do_admm) THEN
2386 CALL admm_correct_for_eigenvalues(ispin, admm_env, ks_rmpv(ispin)%matrix)
2387 END IF
2388 CALL get_mo_set(mo_set=mos(ispin), mo_coeff=mo_coeff, &
2389 eigenvalues=mo_eigenvalues)
2390 IF (ASSOCIATED(qs_env%mo_derivs)) THEN
2391 mo_coeff_deriv => qs_env%mo_derivs(ispin)%matrix
2392 ELSE
2393 mo_coeff_deriv => null()
2394 END IF
2395 CALL calculate_subspace_eigenvalues(mo_coeff, ks_rmpv(ispin)%matrix, mo_eigenvalues, &
2396 do_rotation=.true., &
2397 co_rotate_dbcsr=mo_coeff_deriv)
2398 CALL set_mo_occupation(mo_set=mos(ispin))
2399 IF (dft_control%do_admm) THEN
2400 CALL admm_uncorrect_for_eigenvalues(ispin, admm_env, ks_rmpv(ispin)%matrix)
2401 END IF
2402 END DO
2403 END IF
2404 END IF
2405 END IF
2406
2407 IF (defer_molden) THEN
2408 IF (ASSOCIATED(unoccupied_orbs)) THEN
2409 IF (output_unit > 0) THEN
2410 WRITE (output_unit, '(/,T2,A,I6,A)') &
2411 "MO_MOLDEN| Writing ", nlumos, " unoccupied orbitals to molden file"
2412 END IF
2413 CALL write_mos_molden(mos, qs_kind_set, particle_set, sprint_section, cell=cell, &
2414 unoccupied_orbs=unoccupied_orbs, &
2415 unoccupied_evals=unoccupied_evals, &
2416 qs_env=qs_env, calc_energies=.true.)
2417 END IF
2418 END IF
2419
2420 ! DOS printout after the SCF cycle is completed
2421 IF (do_dos) THEN
2422 IF (do_kpoints) THEN
2423 CALL calculate_dos_kp(qs_env, dft_section)
2424 IF (do_curve) CALL calculate_dos_kp(qs_env, dft_section, write_curve_output=.true.)
2425 ELSE
2426 CALL get_qs_env(qs_env, mos=mos)
2427 IF (ASSOCIATED(unoccupied_evals)) THEN
2428 CALL calculate_dos(mos, dft_section, unoccupied_evals=unoccupied_evals, &
2429 smearing_enabled=dft_control%smear)
2430 IF (do_curve) CALL calculate_dos(mos, dft_section, unoccupied_evals=unoccupied_evals, &
2431 smearing_enabled=dft_control%smear, write_curve_output=.true.)
2432 ELSE
2433 CALL calculate_dos(mos, dft_section, smearing_enabled=dft_control%smear)
2434 IF (do_curve) CALL calculate_dos(mos, dft_section, smearing_enabled=dft_control%smear, &
2435 write_curve_output=.true.)
2436 END IF
2437 END IF
2438 END IF
2439
2440 ! Print projected density-of-states outputs
2441 IF (do_projected_dos) THEN
2442 IF (do_kpoints) THEN
2443 CALL calculate_projected_dos_kp(qs_env, dft_section, pdos_print_key="PRINT%DOS", &
2444 write_pdos=do_pdos, write_pdos_curve=do_curve)
2445 ELSE
2446 CALL get_qs_env(qs_env, &
2447 mos=mos, &
2448 matrix_ks=ks_rmpv)
2449 DO ispin = 1, dft_control%nspins
2450 IF (dft_control%nspins == 2) THEN
2451 IF (ASSOCIATED(unoccupied_orbs)) THEN
2452 CALL calculate_projected_dos(mos(ispin), atomic_kind_set, &
2453 qs_kind_set, particle_set, qs_env, dft_section, ispin=ispin, &
2454 unoccupied_orbs=unoccupied_orbs(ispin), &
2455 unoccupied_evals=unoccupied_evals(ispin), &
2456 pdos_print_key="PRINT%DOS", write_pdos=do_pdos, write_pdos_curve=do_curve)
2457 ELSE
2458 CALL calculate_projected_dos(mos(ispin), atomic_kind_set, &
2459 qs_kind_set, particle_set, qs_env, dft_section, ispin=ispin, &
2460 pdos_print_key="PRINT%DOS", write_pdos=do_pdos, write_pdos_curve=do_curve)
2461 END IF
2462 ELSE
2463 IF (ASSOCIATED(unoccupied_orbs)) THEN
2464 CALL calculate_projected_dos(mos(ispin), atomic_kind_set, &
2465 qs_kind_set, particle_set, qs_env, dft_section, &
2466 unoccupied_orbs=unoccupied_orbs(ispin), &
2467 unoccupied_evals=unoccupied_evals(ispin), &
2468 pdos_print_key="PRINT%DOS", write_pdos=do_pdos, write_pdos_curve=do_curve)
2469 ELSE
2470 CALL calculate_projected_dos(mos(ispin), atomic_kind_set, &
2471 qs_kind_set, particle_set, qs_env, dft_section, &
2472 pdos_print_key="PRINT%DOS", write_pdos=do_pdos, write_pdos_curve=do_curve)
2473 END IF
2474 END IF
2475 END DO
2476 END IF
2477 END IF
2478 IF (ASSOCIATED(unoccupied_orbs)) THEN
2479 DO ispin = 1, dft_control%nspins
2480 DEALLOCATE (unoccupied_evals(ispin)%array)
2481 CALL cp_fm_release(unoccupied_orbs(ispin))
2482 END DO
2483 DEALLOCATE (unoccupied_evals)
2484 DEALLOCATE (unoccupied_orbs)
2485 END IF
2486 END IF
2487
2488 ! Integrated absolute spin density and spin contamination ***
2489 IF (dft_control%nspins == 2) THEN
2490 total_spin_dens = 0.0_dp
2491 total_abs_spin_dens = 0.0_dp
2492 IF (dft_control%qs_control%gapw) THEN
2493 CALL get_qs_env(qs_env, qs_charges=qs_charges)
2494 total_spin_dens = qs_charges%total_rho_hard_spin - &
2495 qs_charges%total_rho_soft_spin
2496 total_abs_spin_dens = qs_charges%total_rho_hard_abs_spin - &
2497 qs_charges%total_rho_soft_abs_spin
2498 END IF
2499 CALL get_qs_env(qs_env, mos=mos)
2500 CALL get_qs_env(qs_env=qs_env, pw_env=pw_env)
2501 CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool, &
2502 pw_pools=pw_pools)
2503 CALL auxbas_pw_pool%create_pw(wf_r)
2504 CALL pw_copy(rho_r(1), wf_r)
2505 CALL pw_axpy(rho_r(2), wf_r, alpha=-1._dp)
2506 total_spin_dens = total_spin_dens + pw_integrate_function(wf_r)
2507 IF (output_unit > 0) WRITE (unit=output_unit, fmt='(/,(T3,A,T61,F20.10))') &
2508 "Integrated spin density: ", total_spin_dens
2509 total_abs_spin_dens = total_abs_spin_dens + pw_integrate_function(wf_r, oprt="ABS")
2510 IF (output_unit > 0) WRITE (unit=output_unit, fmt='((T3,A,T61,F20.10))') &
2511 "Integrated absolute spin density: ", total_abs_spin_dens
2512 CALL auxbas_pw_pool%give_back_pw(wf_r)
2513 !
2514 ! XXX Fix Me XXX
2515 ! should be extended to the case where added MOs are present
2516 ! should be extended to the k-point case
2517 !
2518 IF (.NOT. do_kpoints) THEN
2519 all_equal = .true.
2520 DO ispin = 1, dft_control%nspins
2521 CALL get_mo_set(mo_set=mos(ispin), &
2522 occupation_numbers=occupation_numbers, &
2523 homo=homo, &
2524 nmo=nmo, &
2525 maxocc=maxocc)
2526 IF (nmo > 0) THEN
2527 all_equal = all_equal .AND. &
2528 (all(occupation_numbers(1:homo) == maxocc) .AND. &
2529 all(occupation_numbers(homo + 1:nmo) == 0.0_dp))
2530 END IF
2531 END DO
2532 IF (all_equal) THEN
2533 CALL get_qs_env(qs_env=qs_env, &
2534 matrix_s=matrix_s, &
2535 energy=energy)
2536 CALL compute_s_square(mos=mos, matrix_s=matrix_s, s_square=s_square, &
2537 s_square_ideal=s_square_ideal)
2538 IF (output_unit > 0) WRITE (unit=output_unit, fmt='(T3,A,T51,2F15.6)') &
2539 "Ideal and single determinant S**2 : ", s_square_ideal, s_square
2540 energy%s_square = s_square
2541 END IF
2542 END IF
2543 END IF
2544
2545 CALL timestop(handle)
2546
2547 END SUBROUTINE write_mo_dependent_results
2548
2549! **************************************************************************************************
2550!> \brief Write QS results always available (if switched on through the print_keys)
2551!> Can be called from ls_scf
2552!> \param qs_env the qs_env in which the qs_env lives
2553! **************************************************************************************************
2554 SUBROUTINE write_mo_free_results(qs_env)
2555 TYPE(qs_environment_type), POINTER :: qs_env
2556
2557 CHARACTER(len=*), PARAMETER :: routinen = 'write_mo_free_results'
2558 CHARACTER(len=1), DIMENSION(3), PARAMETER :: cdir = ["x", "y", "z"]
2559
2560 CHARACTER(LEN=2) :: element_symbol
2561 CHARACTER(LEN=default_path_length) :: filename, mpi_filename, my_pos_cube, &
2562 my_pos_voro
2563 CHARACTER(LEN=default_string_length) :: name, print_density
2564 INTEGER :: after, handle, i, iat, iatom, id, ikind, img, iso, ispin, iw, l, n_rep_hf, nat, &
2565 natom, nd(3), ngto, niso, nkind, np, nr, output_unit, print_level, should_print_bqb, &
2566 should_print_voro, unit_nr, unit_nr_voro
2567 LOGICAL :: append_cube, append_voro, do_hfx, do_kpoints, mpi_io, omit_headers, print_it, &
2568 rho_r_valid, voro_print_txt, write_ks, write_xc, xrd_interface
2569 REAL(kind=dp) :: norm_factor, q_max, rho_hard, rho_soft, &
2570 rho_total, rho_total_rspace, udvol, &
2571 volume, zeff
2572 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: zcharge
2573 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :) :: bfun
2574 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :, :) :: aedens, ccdens, ppdens
2575 REAL(kind=dp), DIMENSION(3) :: dr
2576 REAL(kind=dp), DIMENSION(:), POINTER :: my_q0
2577 TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
2578 TYPE(atomic_kind_type), POINTER :: atomic_kind
2579 TYPE(cell_type), POINTER :: cell
2580 TYPE(cp_logger_type), POINTER :: logger
2581 TYPE(cp_section_key) :: e_density_section
2582 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_hr
2583 TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: ks_rmpv, matrix_vxc, rho_ao
2584 TYPE(dft_control_type), POINTER :: dft_control
2585 TYPE(grid_atom_type), POINTER :: grid_atom
2586 TYPE(iao_env_type) :: iao_env
2587 TYPE(mp_para_env_type), POINTER :: para_env
2588 TYPE(particle_list_type), POINTER :: particles
2589 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
2590 TYPE(pw_c1d_gs_type) :: aux_g, rho_elec_gspace
2591 TYPE(pw_c1d_gs_type), POINTER :: rho0_s_gs, rho_core, rhoz_cneo_s_gs
2592 TYPE(pw_env_type), POINTER :: pw_env
2593 TYPE(pw_pool_p_type), DIMENSION(:), POINTER :: pw_pools
2594 TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
2595 TYPE(pw_r3d_rs_type) :: aux_r, rho_elec_rspace, wf_r
2596 TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: rho_r
2597 TYPE(pw_r3d_rs_type), POINTER :: mb_rho, v_hartree_rspace, vee
2598 TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
2599 TYPE(qs_kind_type), POINTER :: qs_kind
2600 TYPE(qs_rho_type), POINTER :: rho
2601 TYPE(qs_subsys_type), POINTER :: subsys
2602 TYPE(rho0_mpole_type), POINTER :: rho0_mpole
2603 TYPE(rho_atom_type), DIMENSION(:), POINTER :: rho_atom_set
2604 TYPE(rho_atom_type), POINTER :: rho_atom
2605 TYPE(section_vals_type), POINTER :: dft_section, hfx_section, input, &
2606 print_key, print_key_bqb, &
2607 print_key_voro, xc_section
2608
2609 CALL timeset(routinen, handle)
2610 NULLIFY (cell, dft_control, pw_env, auxbas_pw_pool, pw_pools, hfx_section, &
2611 atomic_kind_set, qs_kind_set, particle_set, rho, ks_rmpv, rho_ao, rho_r, &
2612 dft_section, xc_section, input, particles, subsys, matrix_vxc, v_hartree_rspace, &
2613 vee)
2614
2615 logger => cp_get_default_logger()
2616 output_unit = cp_logger_get_default_io_unit(logger)
2617
2618 cpassert(ASSOCIATED(qs_env))
2619 CALL get_qs_env(qs_env, &
2620 atomic_kind_set=atomic_kind_set, &
2621 qs_kind_set=qs_kind_set, &
2622 particle_set=particle_set, &
2623 cell=cell, &
2624 para_env=para_env, &
2625 dft_control=dft_control, &
2626 input=input, &
2627 do_kpoints=do_kpoints, &
2628 subsys=subsys)
2629 dft_section => section_vals_get_subs_vals(input, "DFT")
2630 CALL qs_subsys_get(subsys, particles=particles)
2631
2632 CALL get_qs_env(qs_env, rho=rho)
2633 CALL qs_rho_get(rho, rho_r=rho_r)
2634
2635 CALL get_qs_env(qs_env, nkind=nkind, natom=natom)
2636 ALLOCATE (zcharge(natom))
2637 DO ikind = 1, nkind
2638 CALL get_qs_kind(qs_kind_set(ikind), zeff=zeff)
2639 CALL get_atomic_kind(atomic_kind_set(ikind), natom=nat)
2640 DO iatom = 1, nat
2641 iat = atomic_kind_set(ikind)%atom_list(iatom)
2642 zcharge(iat) = zeff
2643 END DO
2644 END DO
2645
2646 ! Print the total density (electronic + core charge)
2647 IF (btest(cp_print_key_should_output(logger%iter_info, input, &
2648 "DFT%PRINT%TOT_DENSITY_CUBE"), cp_p_file)) THEN
2649 NULLIFY (rho_core, rho0_s_gs, rhoz_cneo_s_gs)
2650 append_cube = section_get_lval(input, "DFT%PRINT%TOT_DENSITY_CUBE%APPEND")
2651 my_pos_cube = "REWIND"
2652 IF (append_cube) THEN
2653 my_pos_cube = "APPEND"
2654 END IF
2655
2656 CALL get_qs_env(qs_env=qs_env, pw_env=pw_env, rho_core=rho_core, &
2657 rho0_s_gs=rho0_s_gs, rhoz_cneo_s_gs=rhoz_cneo_s_gs)
2658 CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool, &
2659 pw_pools=pw_pools)
2660 CALL auxbas_pw_pool%create_pw(wf_r)
2661 IF (dft_control%qs_control%gapw) THEN
2662 IF (dft_control%qs_control%gapw_control%nopaw_as_gpw) THEN
2663 CALL pw_axpy(rho_core, rho0_s_gs)
2664 IF (ASSOCIATED(rhoz_cneo_s_gs)) THEN
2665 CALL pw_axpy(rhoz_cneo_s_gs, rho0_s_gs)
2666 END IF
2667 CALL pw_transfer(rho0_s_gs, wf_r)
2668 CALL pw_axpy(rho_core, rho0_s_gs, -1.0_dp)
2669 IF (ASSOCIATED(rhoz_cneo_s_gs)) THEN
2670 CALL pw_axpy(rhoz_cneo_s_gs, rho0_s_gs, -1.0_dp)
2671 END IF
2672 ELSE
2673 IF (ASSOCIATED(rhoz_cneo_s_gs)) THEN
2674 CALL pw_axpy(rhoz_cneo_s_gs, rho0_s_gs)
2675 END IF
2676 CALL pw_transfer(rho0_s_gs, wf_r)
2677 IF (ASSOCIATED(rhoz_cneo_s_gs)) THEN
2678 CALL pw_axpy(rhoz_cneo_s_gs, rho0_s_gs, -1.0_dp)
2679 END IF
2680 END IF
2681 ELSE
2682 CALL pw_transfer(rho_core, wf_r)
2683 END IF
2684 DO ispin = 1, dft_control%nspins
2685 CALL pw_axpy(rho_r(ispin), wf_r)
2686 END DO
2687 filename = "TOTAL_DENSITY"
2688 mpi_io = .true.
2689 unit_nr = cp_print_key_unit_nr(logger, input, "DFT%PRINT%TOT_DENSITY_CUBE", &
2690 extension=".cube", middle_name=trim(filename), file_position=my_pos_cube, &
2691 log_filename=.false., mpi_io=mpi_io)
2692 CALL cp_pw_to_cube(wf_r, unit_nr, "TOTAL DENSITY", &
2693 particles=particles, zeff=zcharge, &
2694 stride=section_get_ivals(dft_section, "PRINT%TOT_DENSITY_CUBE%STRIDE"), &
2695 max_file_size_mb=section_get_rval(dft_section, "PRINT%TOT_DENSITY_CUBE%MAX_FILE_SIZE_MB"), &
2696 mpi_io=mpi_io)
2697 CALL cp_print_key_finished_output(unit_nr, logger, input, &
2698 "DFT%PRINT%TOT_DENSITY_CUBE", mpi_io=mpi_io)
2699 CALL auxbas_pw_pool%give_back_pw(wf_r)
2700 END IF
2701
2702 e_density_section = cube_or_openpmd(input, str_e_density_cubes, str_e_density_openpmd, logger)
2703
2704 ! Write cube file with electron density
2705 IF (e_density_section%do_output) THEN
2706 CALL section_vals_val_get(dft_section, &
2707 keyword_name=e_density_section%concat_to_relative("%DENSITY_INCLUDE"), &
2708 c_val=print_density)
2709 print_density = trim(print_density)
2710 ! For openPMD, refer to access modes instead of APPEND key
2711 IF (e_density_section%grid_output == grid_output_cubes) THEN
2712 append_cube = section_get_lval(input, e_density_section%concat_to_absolute("%APPEND"))
2713 END IF
2714 my_pos_cube = "REWIND"
2715 IF (append_cube) THEN
2716 my_pos_cube = "APPEND"
2717 END IF
2718 ! Write the info on core densities for the interface between cp2k and the XRD code
2719 ! together with the valence density they are used to compute the form factor (Fourier transform)
2720 IF (e_density_section%grid_output == grid_output_cubes) THEN
2721 xrd_interface = section_get_lval(input, e_density_section%concat_to_absolute("%XRD_INTERFACE"))
2722 ELSE
2723 ! Unimplemented for openPMD, since this does not use the regular routines
2724 xrd_interface = .false.
2725 END IF
2726
2727 IF (xrd_interface) THEN
2728 !cube file only contains soft density (GAPW)
2729 IF (dft_control%qs_control%gapw) print_density = "SOFT_DENSITY"
2730
2731 filename = "ELECTRON_DENSITY"
2732 unit_nr = cp_print_key_unit_nr(logger, input, e_density_section%absolute_section_key, &
2733 extension=".xrd", middle_name=trim(filename), &
2734 file_position=my_pos_cube, log_filename=.false.)
2735 ngto = section_get_ival(input, e_density_section%concat_to_absolute("%NGAUSS"))
2736 IF (output_unit > 0) THEN
2737 INQUIRE (unit=unit_nr, name=filename)
2738 WRITE (unit=output_unit, fmt="(/,T2,A,/,/,T2,A)") &
2739 "The electron density (atomic part) is written to the file:", &
2740 trim(filename)
2741 END IF
2742
2743 xc_section => section_vals_get_subs_vals(input, "DFT%XC")
2744 nkind = SIZE(atomic_kind_set)
2745 IF (unit_nr > 0) THEN
2746 WRITE (unit_nr, *) "Atomic (core) densities"
2747 WRITE (unit_nr, *) "Unit cell"
2748 WRITE (unit_nr, fmt="(3F20.12)") cell%hmat(1, 1), cell%hmat(1, 2), cell%hmat(1, 3)
2749 WRITE (unit_nr, fmt="(3F20.12)") cell%hmat(2, 1), cell%hmat(2, 2), cell%hmat(2, 3)
2750 WRITE (unit_nr, fmt="(3F20.12)") cell%hmat(3, 1), cell%hmat(3, 2), cell%hmat(3, 3)
2751 WRITE (unit_nr, *) "Atomic types"
2752 WRITE (unit_nr, *) nkind
2753 END IF
2754 ! calculate atomic density and core density
2755 ALLOCATE (ppdens(ngto, 2, nkind), aedens(ngto, 2, nkind), ccdens(ngto, 2, nkind))
2756 DO ikind = 1, nkind
2757 atomic_kind => atomic_kind_set(ikind)
2758 qs_kind => qs_kind_set(ikind)
2759 CALL get_atomic_kind(atomic_kind, name=name, element_symbol=element_symbol)
2760 CALL calculate_atomic_density(ppdens(:, :, ikind), atomic_kind, qs_kind, ngto, &
2761 iunit=output_unit, confine=.true.)
2762 CALL calculate_atomic_density(aedens(:, :, ikind), atomic_kind, qs_kind, ngto, &
2763 iunit=output_unit, allelectron=.true., confine=.true.)
2764 ccdens(:, 1, ikind) = aedens(:, 1, ikind)
2765 ccdens(:, 2, ikind) = 0._dp
2766 CALL project_function_a(ccdens(1:ngto, 2, ikind), ccdens(1:ngto, 1, ikind), &
2767 ppdens(1:ngto, 2, ikind), ppdens(1:ngto, 1, ikind), 0)
2768 ccdens(:, 2, ikind) = aedens(:, 2, ikind) - ccdens(:, 2, ikind)
2769 IF (unit_nr > 0) THEN
2770 WRITE (unit_nr, fmt="(I6,A10,A20)") ikind, trim(element_symbol), trim(name)
2771 WRITE (unit_nr, fmt="(I6)") ngto
2772 WRITE (unit_nr, *) " Total density"
2773 WRITE (unit_nr, fmt="(2G24.12)") (aedens(i, 1, ikind), aedens(i, 2, ikind), i=1, ngto)
2774 WRITE (unit_nr, *) " Core density"
2775 WRITE (unit_nr, fmt="(2G24.12)") (ccdens(i, 1, ikind), ccdens(i, 2, ikind), i=1, ngto)
2776 END IF
2777 NULLIFY (atomic_kind)
2778 END DO
2779
2780 IF (dft_control%qs_control%gapw) THEN
2781 CALL get_qs_env(qs_env=qs_env, rho_atom_set=rho_atom_set)
2782
2783 IF (unit_nr > 0) THEN
2784 WRITE (unit_nr, *) "Coordinates and GAPW density"
2785 END IF
2786 np = particles%n_els
2787 DO iat = 1, np
2788 CALL get_atomic_kind(particles%els(iat)%atomic_kind, kind_number=ikind)
2789 CALL get_qs_kind(qs_kind_set(ikind), grid_atom=grid_atom)
2790 rho_atom => rho_atom_set(iat)
2791 IF (ASSOCIATED(rho_atom%rho_rad_h(1)%r_coef)) THEN
2792 nr = SIZE(rho_atom%rho_rad_h(1)%r_coef, 1)
2793 niso = SIZE(rho_atom%rho_rad_h(1)%r_coef, 2)
2794 ELSE
2795 nr = 0
2796 niso = 0
2797 END IF
2798 CALL para_env%sum(nr)
2799 CALL para_env%sum(niso)
2800
2801 ALLOCATE (bfun(nr, niso))
2802 bfun = 0._dp
2803 DO ispin = 1, dft_control%nspins
2804 IF (ASSOCIATED(rho_atom%rho_rad_h(1)%r_coef)) THEN
2805 bfun(:, :) = bfun + rho_atom%rho_rad_h(ispin)%r_coef - rho_atom%rho_rad_s(ispin)%r_coef
2806 END IF
2807 END DO
2808 CALL para_env%sum(bfun)
2809 ccdens(:, 1, ikind) = ppdens(:, 1, ikind)
2810 ccdens(:, 2, ikind) = 0._dp
2811 IF (unit_nr > 0) THEN
2812 WRITE (unit_nr, '(I10,I5,3f12.6)') iat, ikind, particles%els(iat)%r
2813 END IF
2814 DO iso = 1, niso
2815 l = indso(1, iso)
2816 CALL project_function_b(ccdens(:, 2, ikind), ccdens(:, 1, ikind), bfun(:, iso), grid_atom, l)
2817 IF (unit_nr > 0) THEN
2818 WRITE (unit_nr, fmt="(3I6)") iso, l, ngto
2819 WRITE (unit_nr, fmt="(2G24.12)") (ccdens(i, 1, ikind), ccdens(i, 2, ikind), i=1, ngto)
2820 END IF
2821 END DO
2822 DEALLOCATE (bfun)
2823 END DO
2824 ELSE
2825 IF (unit_nr > 0) THEN
2826 WRITE (unit_nr, *) "Coordinates"
2827 np = particles%n_els
2828 DO iat = 1, np
2829 CALL get_atomic_kind(particles%els(iat)%atomic_kind, kind_number=ikind)
2830 WRITE (unit_nr, '(I10,I5,3f12.6)') iat, ikind, particles%els(iat)%r
2831 END DO
2832 END IF
2833 END IF
2834
2835 DEALLOCATE (ppdens, aedens, ccdens)
2836
2837 CALL cp_print_key_finished_output(unit_nr, logger, input, &
2838 e_density_section%absolute_section_key)
2839
2840 END IF
2841 IF (dft_control%qs_control%gapw .AND. print_density == "TOTAL_DENSITY") THEN
2842 ! total density in g-space not implemented for k-points
2843 cpassert(.NOT. do_kpoints)
2844 ! Print total electronic density
2845 CALL get_qs_env(qs_env=qs_env, &
2846 pw_env=pw_env)
2847 CALL pw_env_get(pw_env=pw_env, &
2848 auxbas_pw_pool=auxbas_pw_pool, &
2849 pw_pools=pw_pools)
2850 CALL auxbas_pw_pool%create_pw(pw=rho_elec_rspace)
2851 CALL pw_zero(rho_elec_rspace)
2852 CALL auxbas_pw_pool%create_pw(pw=rho_elec_gspace)
2853 CALL pw_zero(rho_elec_gspace)
2854 CALL get_pw_grid_info(pw_grid=rho_elec_gspace%pw_grid, &
2855 dr=dr, &
2856 vol=volume)
2857 q_max = sqrt(sum((pi/dr(:))**2))
2858 CALL calculate_rhotot_elec_gspace(qs_env=qs_env, &
2859 auxbas_pw_pool=auxbas_pw_pool, &
2860 rhotot_elec_gspace=rho_elec_gspace, &
2861 q_max=q_max, &
2862 rho_hard=rho_hard, &
2863 rho_soft=rho_soft)
2864 rho_total = rho_hard + rho_soft
2865 CALL get_pw_grid_info(pw_grid=rho_elec_gspace%pw_grid, &
2866 vol=volume)
2867 ! rhotot pw coefficients are by default scaled by grid volume
2868 ! need to undo this to get proper charge from printed cube
2869 CALL pw_scale(rho_elec_gspace, 1.0_dp/volume)
2870
2871 CALL pw_transfer(rho_elec_gspace, rho_elec_rspace)
2872 rho_total_rspace = pw_integrate_function(rho_elec_rspace, isign=-1)
2873 filename = "TOTAL_ELECTRON_DENSITY"
2874 mpi_io = .true.
2875 unit_nr = e_density_section%print_key_unit_nr( &
2876 logger, &
2877 input, &
2878 e_density_section%absolute_section_key, &
2879 extension=".cube", &
2880 middle_name=trim(filename), &
2881 file_position=my_pos_cube, &
2882 log_filename=.false., &
2883 mpi_io=mpi_io, &
2884 fout=mpi_filename, &
2885 openpmd_basename="dft-total-electron-density", &
2886 openpmd_unit_dimension=openpmd_unit_dimension_density, &
2887 openpmd_unit_si=openpmd_unit_si_density, &
2888 sim_time=qs_env%sim_time)
2889 IF (output_unit > 0) THEN
2890 IF (.NOT. mpi_io) THEN
2891 INQUIRE (unit=unit_nr, name=filename)
2892 ELSE
2893 filename = mpi_filename
2894 END IF
2895 CALL print_density_output_message(output_unit, "The total electron density", &
2896 e_density_section, filename)
2897 WRITE (unit=output_unit, fmt="(/,(T2,A,F20.10))") &
2898 "q(max) [1/Angstrom] :", q_max/angstrom, &
2899 "Soft electronic charge (G-space) :", rho_soft, &
2900 "Hard electronic charge (G-space) :", rho_hard, &
2901 "Total electronic charge (G-space):", rho_total, &
2902 "Total electronic charge (R-space):", rho_total_rspace
2903 END IF
2904 CALL e_density_section%write_pw(rho_elec_rspace, unit_nr, "TOTAL ELECTRON DENSITY", &
2905 particles=particles, zeff=zcharge, &
2906 stride=section_get_ivals(dft_section, e_density_section%concat_to_relative("%STRIDE")), mpi_io=mpi_io)
2907 CALL e_density_section%print_key_finished_output(unit_nr, logger, input, &
2908 e_density_section%absolute_section_key, mpi_io=mpi_io)
2909 ! Print total spin density for spin-polarized systems
2910 IF (dft_control%nspins > 1) THEN
2911 CALL pw_zero(rho_elec_gspace)
2912 CALL pw_zero(rho_elec_rspace)
2913 CALL calculate_rhotot_elec_gspace(qs_env=qs_env, &
2914 auxbas_pw_pool=auxbas_pw_pool, &
2915 rhotot_elec_gspace=rho_elec_gspace, &
2916 q_max=q_max, &
2917 rho_hard=rho_hard, &
2918 rho_soft=rho_soft, &
2919 fsign=-1.0_dp)
2920 rho_total = rho_hard + rho_soft
2921
2922 ! rhotot pw coefficients are by default scaled by grid volume
2923 ! need to undo this to get proper charge from printed cube
2924 CALL pw_scale(rho_elec_gspace, 1.0_dp/volume)
2925
2926 CALL pw_transfer(rho_elec_gspace, rho_elec_rspace)
2927 rho_total_rspace = pw_integrate_function(rho_elec_rspace, isign=-1)
2928 filename = "TOTAL_SPIN_DENSITY"
2929 mpi_io = .true.
2930 unit_nr = e_density_section%print_key_unit_nr( &
2931 logger, &
2932 input, &
2933 e_density_section%absolute_section_key, &
2934 extension=".cube", &
2935 middle_name=trim(filename), &
2936 file_position=my_pos_cube, &
2937 log_filename=.false., &
2938 mpi_io=mpi_io, &
2939 fout=mpi_filename, &
2940 openpmd_basename="dft-total-spin-density", &
2941 openpmd_unit_dimension=openpmd_unit_dimension_density, &
2942 openpmd_unit_si=openpmd_unit_si_density, &
2943 sim_time=qs_env%sim_time)
2944 IF (output_unit > 0) THEN
2945 IF (.NOT. mpi_io .AND. e_density_section%grid_output == grid_output_cubes) THEN
2946 INQUIRE (unit=unit_nr, name=filename)
2947 ELSE
2948 filename = mpi_filename
2949 END IF
2950 CALL print_density_output_message(output_unit, "The total spin density", &
2951 e_density_section, filename)
2952 WRITE (unit=output_unit, fmt="(/,(T2,A,F20.10))") &
2953 "q(max) [1/Angstrom] :", q_max/angstrom, &
2954 "Soft part of the spin density (G-space):", rho_soft, &
2955 "Hard part of the spin density (G-space):", rho_hard, &
2956 "Total spin density (G-space) :", rho_total, &
2957 "Total spin density (R-space) :", rho_total_rspace
2958 END IF
2959 CALL e_density_section%write_pw(rho_elec_rspace, unit_nr, "TOTAL SPIN DENSITY", &
2960 particles=particles, zeff=zcharge, &
2961 stride=section_get_ivals(dft_section, e_density_section%concat_to_relative("%STRIDE")), mpi_io=mpi_io)
2962 CALL e_density_section%print_key_finished_output(unit_nr, logger, input, &
2963 e_density_section%absolute_section_key, mpi_io=mpi_io)
2964 END IF
2965 CALL auxbas_pw_pool%give_back_pw(rho_elec_gspace)
2966 CALL auxbas_pw_pool%give_back_pw(rho_elec_rspace)
2967
2968 ELSE IF (print_density == "SOFT_DENSITY" .OR. .NOT. dft_control%qs_control%gapw) THEN
2969 IF (dft_control%nspins > 1) THEN
2970 CALL get_qs_env(qs_env=qs_env, &
2971 pw_env=pw_env)
2972 CALL pw_env_get(pw_env=pw_env, &
2973 auxbas_pw_pool=auxbas_pw_pool, &
2974 pw_pools=pw_pools)
2975 CALL auxbas_pw_pool%create_pw(pw=rho_elec_rspace)
2976 CALL pw_copy(rho_r(1), rho_elec_rspace)
2977 CALL pw_axpy(rho_r(2), rho_elec_rspace)
2978 filename = "ELECTRON_DENSITY"
2979 mpi_io = .true.
2980 unit_nr = e_density_section%print_key_unit_nr( &
2981 logger, &
2982 input, &
2983 e_density_section%absolute_section_key, &
2984 extension=".cube", &
2985 middle_name=trim(filename), &
2986 file_position=my_pos_cube, &
2987 log_filename=.false., &
2988 mpi_io=mpi_io, &
2989 fout=mpi_filename, &
2990 openpmd_basename="dft-electron-density", &
2991 openpmd_unit_dimension=openpmd_unit_dimension_density, &
2992 openpmd_unit_si=openpmd_unit_si_density, &
2993 sim_time=qs_env%sim_time)
2994 IF (output_unit > 0) THEN
2995 IF (.NOT. mpi_io .AND. e_density_section%grid_output == grid_output_cubes) THEN
2996 INQUIRE (unit=unit_nr, name=filename)
2997 ELSE
2998 filename = mpi_filename
2999 END IF
3000 CALL print_density_output_message(output_unit, "The sum of alpha and beta density", &
3001 e_density_section, filename)
3002 END IF
3003 CALL e_density_section%write_pw(rho_elec_rspace, unit_nr, "SUM OF ALPHA AND BETA DENSITY", &
3004 particles=particles, zeff=zcharge, stride=section_get_ivals(dft_section, e_density_section%concat_to_relative("%STRIDE")), &
3005 mpi_io=mpi_io)
3006 CALL e_density_section%print_key_finished_output(unit_nr, logger, input, &
3007 e_density_section%absolute_section_key, mpi_io=mpi_io)
3008 CALL pw_copy(rho_r(1), rho_elec_rspace)
3009 CALL pw_axpy(rho_r(2), rho_elec_rspace, alpha=-1.0_dp)
3010 filename = "SPIN_DENSITY"
3011 mpi_io = .true.
3012 unit_nr = e_density_section%print_key_unit_nr( &
3013 logger, &
3014 input, &
3015 e_density_section%absolute_section_key, &
3016 extension=".cube", &
3017 middle_name=trim(filename), &
3018 file_position=my_pos_cube, &
3019 log_filename=.false., &
3020 mpi_io=mpi_io, &
3021 fout=mpi_filename, &
3022 openpmd_basename="dft-spin-density", &
3023 openpmd_unit_dimension=openpmd_unit_dimension_density, &
3024 openpmd_unit_si=openpmd_unit_si_density, &
3025 sim_time=qs_env%sim_time)
3026 IF (output_unit > 0) THEN
3027 IF (.NOT. mpi_io .AND. e_density_section%grid_output == grid_output_cubes) THEN
3028 INQUIRE (unit=unit_nr, name=filename)
3029 ELSE
3030 filename = mpi_filename
3031 END IF
3032 CALL print_density_output_message(output_unit, "The spin density", &
3033 e_density_section, filename)
3034 END IF
3035 CALL e_density_section%write_pw(rho_elec_rspace, unit_nr, "SPIN DENSITY", &
3036 particles=particles, zeff=zcharge, &
3037 stride=section_get_ivals(dft_section, e_density_section%concat_to_relative("%STRIDE")), mpi_io=mpi_io)
3038 CALL e_density_section%print_key_finished_output(unit_nr, logger, input, &
3039 e_density_section%absolute_section_key, mpi_io=mpi_io)
3040 CALL auxbas_pw_pool%give_back_pw(rho_elec_rspace)
3041 ELSE
3042 filename = "ELECTRON_DENSITY"
3043 mpi_io = .true.
3044 unit_nr = e_density_section%print_key_unit_nr( &
3045 logger, &
3046 input, &
3047 e_density_section%absolute_section_key, &
3048 extension=".cube", &
3049 middle_name=trim(filename), &
3050 file_position=my_pos_cube, &
3051 log_filename=.false., &
3052 mpi_io=mpi_io, &
3053 fout=mpi_filename, &
3054 openpmd_basename="dft-electron-density", &
3055 openpmd_unit_dimension=openpmd_unit_dimension_density, &
3056 openpmd_unit_si=openpmd_unit_si_density, &
3057 sim_time=qs_env%sim_time)
3058 IF (output_unit > 0) THEN
3059 IF (.NOT. mpi_io .AND. e_density_section%grid_output == grid_output_cubes) THEN
3060 INQUIRE (unit=unit_nr, name=filename)
3061 ELSE
3062 filename = mpi_filename
3063 END IF
3064 CALL print_density_output_message(output_unit, "The electron density", &
3065 e_density_section, filename)
3066 END IF
3067 CALL e_density_section%write_pw(rho_r(1), unit_nr, "ELECTRON DENSITY", &
3068 particles=particles, zeff=zcharge, &
3069 stride=section_get_ivals(dft_section, e_density_section%concat_to_relative("%STRIDE")), mpi_io=mpi_io)
3070 CALL e_density_section%print_key_finished_output(unit_nr, logger, input, &
3071 e_density_section%absolute_section_key, mpi_io=mpi_io)
3072 END IF ! nspins
3073
3074 ELSE IF (dft_control%qs_control%gapw .AND. print_density == "TOTAL_HARD_APPROX") THEN
3075 CALL get_qs_env(qs_env=qs_env, pw_env=pw_env, rho0_mpole=rho0_mpole, natom=natom)
3076 CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool, pw_pools=pw_pools)
3077 CALL auxbas_pw_pool%create_pw(rho_elec_rspace)
3078
3079 NULLIFY (my_q0)
3080 ALLOCATE (my_q0(natom))
3081 my_q0 = 0.0_dp
3082
3083 ! (eta/pi)**3: normalization for 3d gaussian of form exp(-eta*r**2)
3084 norm_factor = sqrt((rho0_mpole%zet0_h/pi)**3)
3085
3086 ! store hard part of electronic density in array
3087 DO iat = 1, natom
3088 my_q0(iat) = sum(rho0_mpole%mp_rho(iat)%Q0(1:dft_control%nspins))*norm_factor
3089 END DO
3090 ! multiply coeff with gaussian and put on realspace grid
3091 ! coeff is the gaussian prefactor, eta the gaussian exponent
3092 CALL calculate_rho_resp_all(rho_elec_rspace, coeff=my_q0, natom=natom, eta=rho0_mpole%zet0_h, qs_env=qs_env)
3093 rho_hard = pw_integrate_function(rho_elec_rspace, isign=-1)
3094
3095 rho_soft = 0.0_dp
3096 DO ispin = 1, dft_control%nspins
3097 CALL pw_axpy(rho_r(ispin), rho_elec_rspace)
3098 rho_soft = rho_soft + pw_integrate_function(rho_r(ispin), isign=-1)
3099 END DO
3100
3101 rho_total_rspace = rho_soft + rho_hard
3102
3103 filename = "ELECTRON_DENSITY"
3104 mpi_io = .true.
3105 unit_nr = e_density_section%print_key_unit_nr( &
3106 logger, &
3107 input, &
3108 e_density_section%absolute_section_key, &
3109 extension=".cube", &
3110 middle_name=trim(filename), &
3111 file_position=my_pos_cube, &
3112 log_filename=.false., &
3113 mpi_io=mpi_io, &
3114 fout=mpi_filename, &
3115 openpmd_basename="dft-electron-density", &
3116 openpmd_unit_dimension=openpmd_unit_dimension_density, &
3117 openpmd_unit_si=openpmd_unit_si_density, &
3118 sim_time=qs_env%sim_time)
3119 IF (output_unit > 0) THEN
3120 IF (.NOT. mpi_io .AND. e_density_section%grid_output == grid_output_cubes) THEN
3121 INQUIRE (unit=unit_nr, name=filename)
3122 ELSE
3123 filename = mpi_filename
3124 END IF
3125 CALL print_density_output_message(output_unit, "The electron density", &
3126 e_density_section, filename)
3127 WRITE (unit=output_unit, fmt="(/,(T2,A,F20.10))") &
3128 "Soft electronic charge (R-space) :", rho_soft, &
3129 "Hard electronic charge (R-space) :", rho_hard, &
3130 "Total electronic charge (R-space):", rho_total_rspace
3131 END IF
3132 CALL e_density_section%write_pw(rho_elec_rspace, unit_nr, "ELECTRON DENSITY", &
3133 particles=particles, zeff=zcharge, stride=section_get_ivals(dft_section, e_density_section%concat_to_relative("%STRIDE")), &
3134 mpi_io=mpi_io)
3135 CALL e_density_section%print_key_finished_output(unit_nr, logger, input, &
3136 e_density_section%absolute_section_key, mpi_io=mpi_io)
3137
3138 !------------
3139 IF (dft_control%nspins > 1) THEN
3140 DO iat = 1, natom
3141 my_q0(iat) = (rho0_mpole%mp_rho(iat)%Q0(1) - rho0_mpole%mp_rho(iat)%Q0(2))*norm_factor
3142 END DO
3143 CALL pw_zero(rho_elec_rspace)
3144 CALL calculate_rho_resp_all(rho_elec_rspace, coeff=my_q0, natom=natom, eta=rho0_mpole%zet0_h, qs_env=qs_env)
3145 rho_hard = pw_integrate_function(rho_elec_rspace, isign=-1)
3146
3147 CALL pw_axpy(rho_r(1), rho_elec_rspace)
3148 CALL pw_axpy(rho_r(2), rho_elec_rspace, alpha=-1.0_dp)
3149 rho_soft = pw_integrate_function(rho_r(1), isign=-1) &
3150 - pw_integrate_function(rho_r(2), isign=-1)
3151
3152 rho_total_rspace = rho_soft + rho_hard
3153
3154 filename = "SPIN_DENSITY"
3155 mpi_io = .true.
3156 unit_nr = e_density_section%print_key_unit_nr( &
3157 logger, &
3158 input, &
3159 e_density_section%absolute_section_key, &
3160 extension=".cube", &
3161 middle_name=trim(filename), &
3162 file_position=my_pos_cube, &
3163 log_filename=.false., &
3164 mpi_io=mpi_io, &
3165 fout=mpi_filename, &
3166 openpmd_basename="dft-spin-density", &
3167 openpmd_unit_dimension=openpmd_unit_dimension_density, &
3168 openpmd_unit_si=openpmd_unit_si_density, &
3169 sim_time=qs_env%sim_time)
3170 IF (output_unit > 0) THEN
3171 IF (.NOT. mpi_io .AND. e_density_section%grid_output == grid_output_cubes) THEN
3172 INQUIRE (unit=unit_nr, name=filename)
3173 ELSE
3174 filename = mpi_filename
3175 END IF
3176 CALL print_density_output_message(output_unit, "The spin density", &
3177 e_density_section, filename)
3178 WRITE (unit=output_unit, fmt="(/,(T2,A,F20.10))") &
3179 "Soft part of the spin density :", rho_soft, &
3180 "Hard part of the spin density :", rho_hard, &
3181 "Total spin density (R-space) :", rho_total_rspace
3182 END IF
3183 CALL e_density_section%write_pw(rho_elec_rspace, unit_nr, "SPIN DENSITY", &
3184 particles=particles, zeff=zcharge, &
3185 stride=section_get_ivals(dft_section, e_density_section%concat_to_relative("%STRIDE")), mpi_io=mpi_io)
3186 CALL e_density_section%print_key_finished_output(unit_nr, logger, input, &
3187 e_density_section%absolute_section_key, mpi_io=mpi_io)
3188 END IF ! nspins
3189 CALL auxbas_pw_pool%give_back_pw(rho_elec_rspace)
3190 DEALLOCATE (my_q0)
3191 END IF ! print_density
3192 END IF ! print key
3193
3194 IF (btest(cp_print_key_should_output(logger%iter_info, &
3195 dft_section, "PRINT%ENERGY_WINDOWS"), cp_p_file) .AND. .NOT. do_kpoints) THEN
3196 CALL energy_windows(qs_env)
3197 END IF
3198
3199 ! Print the hartree potential
3200 IF (btest(cp_print_key_should_output(logger%iter_info, input, &
3201 "DFT%PRINT%V_HARTREE_CUBE"), cp_p_file)) THEN
3202
3203 CALL get_qs_env(qs_env=qs_env, &
3204 pw_env=pw_env, &
3205 v_hartree_rspace=v_hartree_rspace)
3206 CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool)
3207 CALL auxbas_pw_pool%create_pw(aux_r)
3208
3209 append_cube = section_get_lval(input, "DFT%PRINT%V_HARTREE_CUBE%APPEND")
3210 my_pos_cube = "REWIND"
3211 IF (append_cube) THEN
3212 my_pos_cube = "APPEND"
3213 END IF
3214 mpi_io = .true.
3215 CALL get_qs_env(qs_env=qs_env, pw_env=pw_env)
3216 CALL pw_env_get(pw_env)
3217 unit_nr = cp_print_key_unit_nr(logger, input, "DFT%PRINT%V_HARTREE_CUBE", &
3218 extension=".cube", middle_name="v_hartree", file_position=my_pos_cube, mpi_io=mpi_io)
3219 udvol = 1.0_dp/v_hartree_rspace%pw_grid%dvol
3220
3221 CALL pw_copy(v_hartree_rspace, aux_r)
3222 CALL pw_scale(aux_r, udvol)
3223
3224 CALL cp_pw_to_cube(aux_r, unit_nr, "HARTREE POTENTIAL", particles=particles, zeff=zcharge, &
3225 stride=section_get_ivals(dft_section, "PRINT%V_HARTREE_CUBE%STRIDE"), &
3226 max_file_size_mb=section_get_rval(dft_section, "PRINT%V_HARTREE_CUBE%MAX_FILE_SIZE_MB"), &
3227 mpi_io=mpi_io)
3228 CALL cp_print_key_finished_output(unit_nr, logger, input, &
3229 "DFT%PRINT%V_HARTREE_CUBE", mpi_io=mpi_io)
3230
3231 CALL auxbas_pw_pool%give_back_pw(aux_r)
3232 END IF
3233
3234 ! Print the external potential
3235 IF (btest(cp_print_key_should_output(logger%iter_info, input, &
3236 "DFT%PRINT%EXTERNAL_POTENTIAL_CUBE"), cp_p_file)) THEN
3237 IF (dft_control%apply_external_potential) THEN
3238 CALL get_qs_env(qs_env=qs_env, pw_env=pw_env, vee=vee)
3239 CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool)
3240 CALL auxbas_pw_pool%create_pw(aux_r)
3241
3242 append_cube = section_get_lval(input, "DFT%PRINT%EXTERNAL_POTENTIAL_CUBE%APPEND")
3243 my_pos_cube = "REWIND"
3244 IF (append_cube) THEN
3245 my_pos_cube = "APPEND"
3246 END IF
3247 mpi_io = .true.
3248 CALL pw_env_get(pw_env)
3249 unit_nr = cp_print_key_unit_nr(logger, input, "DFT%PRINT%EXTERNAL_POTENTIAL_CUBE", &
3250 extension=".cube", middle_name="ext_pot", file_position=my_pos_cube, mpi_io=mpi_io)
3251
3252 CALL pw_copy(vee, aux_r)
3253
3254 CALL cp_pw_to_cube(aux_r, unit_nr, "EXTERNAL POTENTIAL", particles=particles, zeff=zcharge, &
3255 stride=section_get_ivals(dft_section, "PRINT%EXTERNAL_POTENTIAL_CUBE%STRIDE"), &
3256 max_file_size_mb=section_get_rval(dft_section, "PRINT%EXTERNAL_POTENTIAL_CUBE%MAX_FILE_SIZE_MB"), &
3257 mpi_io=mpi_io)
3258 CALL cp_print_key_finished_output(unit_nr, logger, input, &
3259 "DFT%PRINT%EXTERNAL_POTENTIAL_CUBE", mpi_io=mpi_io)
3260
3261 CALL auxbas_pw_pool%give_back_pw(aux_r)
3262 END IF
3263 END IF
3264
3265 ! Print the Electrical Field Components
3266 IF (btest(cp_print_key_should_output(logger%iter_info, input, &
3267 "DFT%PRINT%EFIELD_CUBE"), cp_p_file)) THEN
3268
3269 CALL get_qs_env(qs_env=qs_env, pw_env=pw_env)
3270 CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool)
3271 CALL auxbas_pw_pool%create_pw(aux_r)
3272 CALL auxbas_pw_pool%create_pw(aux_g)
3273
3274 append_cube = section_get_lval(input, "DFT%PRINT%EFIELD_CUBE%APPEND")
3275 my_pos_cube = "REWIND"
3276 IF (append_cube) THEN
3277 my_pos_cube = "APPEND"
3278 END IF
3279 CALL get_qs_env(qs_env=qs_env, pw_env=pw_env, &
3280 v_hartree_rspace=v_hartree_rspace)
3281 CALL pw_env_get(pw_env)
3282 udvol = 1.0_dp/v_hartree_rspace%pw_grid%dvol
3283 DO id = 1, 3
3284 mpi_io = .true.
3285 unit_nr = cp_print_key_unit_nr(logger, input, "DFT%PRINT%EFIELD_CUBE", &
3286 extension=".cube", middle_name="efield_"//cdir(id), file_position=my_pos_cube, &
3287 mpi_io=mpi_io)
3288
3289 CALL pw_transfer(v_hartree_rspace, aux_g)
3290 nd = 0
3291 nd(id) = 1
3292 CALL pw_derive(aux_g, nd)
3293 CALL pw_transfer(aux_g, aux_r)
3294 CALL pw_scale(aux_r, udvol)
3295
3296 CALL cp_pw_to_cube(aux_r, unit_nr, "ELECTRIC FIELD", particles=particles, zeff=zcharge, &
3297 stride=section_get_ivals(dft_section, "PRINT%EFIELD_CUBE%STRIDE"), &
3298 max_file_size_mb=section_get_rval(dft_section, "PRINT%EFIELD_CUBE%MAX_FILE_SIZE_MB"), &
3299 mpi_io=mpi_io)
3300 CALL cp_print_key_finished_output(unit_nr, logger, input, &
3301 "DFT%PRINT%EFIELD_CUBE", mpi_io=mpi_io)
3302 END DO
3303
3304 CALL auxbas_pw_pool%give_back_pw(aux_r)
3305 CALL auxbas_pw_pool%give_back_pw(aux_g)
3306 END IF
3307
3308 ! Write cube files from the local energy
3309 CALL qs_scf_post_local_energy(input, logger, qs_env)
3310
3311 ! Write cube files from the local stress tensor
3312 CALL qs_scf_post_local_stress(input, logger, qs_env)
3313
3314 ! Write cube files from the implicit Poisson solver
3315 CALL qs_scf_post_ps_implicit(input, logger, qs_env)
3316
3317 ! post SCF finite-volume Kubo transport
3318 CALL qs_scf_post_kubo_transport(qs_env)
3319
3320 ! post SCF Transport
3321 CALL qs_scf_post_transport(qs_env)
3322
3323 CALL section_vals_val_get(input, "DFT%PRINT%AO_MATRICES%OMIT_HEADERS", l_val=omit_headers)
3324 ! Write the density matrices
3325 IF (btest(cp_print_key_should_output(logger%iter_info, input, &
3326 "DFT%PRINT%AO_MATRICES/DENSITY"), cp_p_file)) THEN
3327 iw = cp_print_key_unit_nr(logger, input, "DFT%PRINT%AO_MATRICES/DENSITY", &
3328 extension=".Log")
3329 CALL section_vals_val_get(input, "DFT%PRINT%AO_MATRICES%NDIGITS", i_val=after)
3330 CALL qs_rho_get(rho, rho_ao_kp=rho_ao)
3331 after = min(max(after, 1), 16)
3332 DO ispin = 1, dft_control%nspins
3333 DO img = 1, dft_control%nimages
3334 CALL cp_dbcsr_write_sparse_matrix(rho_ao(ispin, img)%matrix, 4, after, qs_env, &
3335 para_env, output_unit=iw, omit_headers=omit_headers)
3336 END DO
3337 END DO
3338 CALL cp_print_key_finished_output(iw, logger, input, &
3339 "DFT%PRINT%AO_MATRICES/DENSITY")
3340 END IF
3341
3342 ! Write the Kohn-Sham matrices
3343 write_ks = btest(cp_print_key_should_output(logger%iter_info, input, &
3344 "DFT%PRINT%AO_MATRICES/KOHN_SHAM_MATRIX"), cp_p_file)
3345 write_xc = btest(cp_print_key_should_output(logger%iter_info, input, &
3346 "DFT%PRINT%AO_MATRICES/MATRIX_VXC"), cp_p_file)
3347 ! we need to update stuff before writing, potentially computing the matrix_vxc
3348 IF (write_ks .OR. write_xc) THEN
3349 IF (write_xc) qs_env%requires_matrix_vxc = .true.
3350 CALL qs_ks_did_change(qs_env%ks_env, rho_changed=.true.)
3351 CALL qs_ks_update_qs_env(qs_env, calculate_forces=.false., &
3352 just_energy=.false.)
3353 IF (write_xc) qs_env%requires_matrix_vxc = .false.
3354 END IF
3355
3356 ! Write the Kohn-Sham matrices
3357 IF (write_ks) THEN
3358 iw = cp_print_key_unit_nr(logger, input, "DFT%PRINT%AO_MATRICES/KOHN_SHAM_MATRIX", &
3359 extension=".Log")
3360 CALL get_qs_env(qs_env=qs_env, matrix_ks_kp=ks_rmpv)
3361 CALL section_vals_val_get(input, "DFT%PRINT%AO_MATRICES%NDIGITS", i_val=after)
3362 after = min(max(after, 1), 16)
3363 DO ispin = 1, dft_control%nspins
3364 DO img = 1, dft_control%nimages
3365 CALL cp_dbcsr_write_sparse_matrix(ks_rmpv(ispin, img)%matrix, 4, after, qs_env, &
3366 para_env, output_unit=iw, omit_headers=omit_headers)
3367 END DO
3368 END DO
3369 CALL cp_print_key_finished_output(iw, logger, input, &
3370 "DFT%PRINT%AO_MATRICES/KOHN_SHAM_MATRIX")
3371 END IF
3372
3373 ! write csr matrices
3374 ! matrices in terms of the PAO basis will be taken care of in pao_post_scf.
3375 IF (.NOT. dft_control%qs_control%pao) THEN
3376 CALL write_ks_matrix_csr(qs_env, input)
3377 CALL write_s_matrix_csr(qs_env, input)
3378 CALL write_hcore_matrix_csr(qs_env, input)
3379 CALL write_p_matrix_csr(qs_env, input)
3380 END IF
3381
3382 ! write adjacency matrix
3383 CALL write_adjacency_matrix(qs_env, input)
3384
3385 ! Write the xc matrix
3386 IF (write_xc) THEN
3387 CALL get_qs_env(qs_env=qs_env, matrix_vxc_kp=matrix_vxc)
3388 cpassert(ASSOCIATED(matrix_vxc))
3389 iw = cp_print_key_unit_nr(logger, input, "DFT%PRINT%AO_MATRICES/MATRIX_VXC", &
3390 extension=".Log")
3391 CALL section_vals_val_get(input, "DFT%PRINT%AO_MATRICES%NDIGITS", i_val=after)
3392 after = min(max(after, 1), 16)
3393 DO ispin = 1, dft_control%nspins
3394 DO img = 1, dft_control%nimages
3395 CALL cp_dbcsr_write_sparse_matrix(matrix_vxc(ispin, img)%matrix, 4, after, qs_env, &
3396 para_env, output_unit=iw, omit_headers=omit_headers)
3397 END DO
3398 END DO
3399 CALL cp_print_key_finished_output(iw, logger, input, &
3400 "DFT%PRINT%AO_MATRICES/MATRIX_VXC")
3401 END IF
3402
3403 ! Write the [H,r] commutator matrices
3404 IF (btest(cp_print_key_should_output(logger%iter_info, input, &
3405 "DFT%PRINT%AO_MATRICES/COMMUTATOR_HR"), cp_p_file)) THEN
3406 iw = cp_print_key_unit_nr(logger, input, "DFT%PRINT%AO_MATRICES/COMMUTATOR_HR", &
3407 extension=".Log")
3408 CALL section_vals_val_get(input, "DFT%PRINT%AO_MATRICES%NDIGITS", i_val=after)
3409 NULLIFY (matrix_hr)
3410 CALL build_com_hr_matrix(qs_env, matrix_hr)
3411 after = min(max(after, 1), 16)
3412 DO img = 1, 3
3413 CALL cp_dbcsr_write_sparse_matrix(matrix_hr(img)%matrix, 4, after, qs_env, &
3414 para_env, output_unit=iw, omit_headers=omit_headers)
3415 END DO
3416 CALL dbcsr_deallocate_matrix_set(matrix_hr)
3417 CALL cp_print_key_finished_output(iw, logger, input, &
3418 "DFT%PRINT%AO_MATRICES/COMMUTATOR_HR")
3419 END IF
3420
3421 ! Compute the Mulliken charges
3422 print_key => section_vals_get_subs_vals(input, "DFT%PRINT%MULLIKEN")
3423 IF (btest(cp_print_key_should_output(logger%iter_info, print_key), cp_p_file)) THEN
3424 unit_nr = cp_print_key_unit_nr(logger, input, "DFT%PRINT%MULLIKEN", extension=".mulliken", log_filename=.false.)
3425 print_level = 1
3426 CALL section_vals_val_get(print_key, "PRINT_GOP", l_val=print_it)
3427 IF (print_it) print_level = 2
3428 CALL section_vals_val_get(print_key, "PRINT_ALL", l_val=print_it)
3429 IF (print_it) print_level = 3
3430 CALL mulliken_population_analysis(qs_env, unit_nr, print_level)
3431 CALL cp_print_key_finished_output(unit_nr, logger, input, "DFT%PRINT%MULLIKEN")
3432 END IF
3433
3434 ! Compute the Hirshfeld charges
3435 print_key => section_vals_get_subs_vals(input, "DFT%PRINT%HIRSHFELD")
3436 IF (btest(cp_print_key_should_output(logger%iter_info, print_key), cp_p_file)) THEN
3437 ! we check if real space density is available
3438 NULLIFY (rho)
3439 CALL get_qs_env(qs_env=qs_env, rho=rho)
3440 CALL qs_rho_get(rho, rho_r_valid=rho_r_valid)
3441 IF (rho_r_valid) THEN
3442 unit_nr = cp_print_key_unit_nr(logger, input, "DFT%PRINT%HIRSHFELD", extension=".hirshfeld", log_filename=.false.)
3443 CALL hirshfeld_charges(qs_env, print_key, unit_nr)
3444 CALL cp_print_key_finished_output(unit_nr, logger, input, "DFT%PRINT%HIRSHFELD")
3445 END IF
3446 END IF
3447
3448 ! Compute EEQ charges
3449 print_key => section_vals_get_subs_vals(input, "DFT%PRINT%EEQ_CHARGES")
3450 IF (btest(cp_print_key_should_output(logger%iter_info, print_key), cp_p_file)) THEN
3451 unit_nr = cp_print_key_unit_nr(logger, input, "DFT%PRINT%EEQ_CHARGES", extension=".eeq", log_filename=.false.)
3452 print_level = 1
3453 CALL eeq_print(qs_env, unit_nr, print_level, ext=.false.)
3454 CALL cp_print_key_finished_output(unit_nr, logger, input, "DFT%PRINT%MULLIKEN")
3455 END IF
3456
3457 ! Do a Voronoi Integration or write a compressed BQB File
3458 print_key_voro => section_vals_get_subs_vals(input, "DFT%PRINT%VORONOI")
3459 print_key_bqb => section_vals_get_subs_vals(input, "DFT%PRINT%E_DENSITY_BQB")
3460 IF (btest(cp_print_key_should_output(logger%iter_info, print_key_voro), cp_p_file)) THEN
3461 should_print_voro = 1
3462 ELSE
3463 should_print_voro = 0
3464 END IF
3465 IF (btest(cp_print_key_should_output(logger%iter_info, print_key_bqb), cp_p_file)) THEN
3466 should_print_bqb = 1
3467 ELSE
3468 should_print_bqb = 0
3469 END IF
3470 IF ((should_print_voro /= 0) .OR. (should_print_bqb /= 0)) THEN
3471
3472 ! we check if real space density is available
3473 NULLIFY (rho)
3474 CALL get_qs_env(qs_env=qs_env, rho=rho)
3475 CALL qs_rho_get(rho, rho_r_valid=rho_r_valid)
3476 IF (rho_r_valid) THEN
3477
3478 IF (dft_control%nspins > 1) THEN
3479 CALL get_qs_env(qs_env=qs_env, &
3480 pw_env=pw_env)
3481 CALL pw_env_get(pw_env=pw_env, &
3482 auxbas_pw_pool=auxbas_pw_pool, &
3483 pw_pools=pw_pools)
3484 NULLIFY (mb_rho)
3485 ALLOCATE (mb_rho)
3486 CALL auxbas_pw_pool%create_pw(pw=mb_rho)
3487 CALL pw_copy(rho_r(1), mb_rho)
3488 CALL pw_axpy(rho_r(2), mb_rho)
3489 !CALL voronoi_analysis(qs_env, rho_elec_rspace, print_key, unit_nr)
3490 ELSE
3491 mb_rho => rho_r(1)
3492 !CALL voronoi_analysis( qs_env, rho_r(1), print_key, unit_nr )
3493 END IF ! nspins
3494
3495 IF (should_print_voro /= 0) THEN
3496 CALL section_vals_val_get(print_key_voro, "OUTPUT_TEXT", l_val=voro_print_txt)
3497 IF (voro_print_txt) THEN
3498 append_voro = section_get_lval(input, "DFT%PRINT%VORONOI%APPEND")
3499 my_pos_voro = "REWIND"
3500 IF (append_voro) THEN
3501 my_pos_voro = "APPEND"
3502 END IF
3503 unit_nr_voro = cp_print_key_unit_nr(logger, input, "DFT%PRINT%VORONOI", extension=".voronoi", &
3504 file_position=my_pos_voro, log_filename=.false.)
3505 ELSE
3506 unit_nr_voro = 0
3507 END IF
3508 ELSE
3509 unit_nr_voro = 0
3510 END IF
3511
3512 CALL entry_voronoi_or_bqb(should_print_voro, should_print_bqb, print_key_voro, print_key_bqb, &
3513 unit_nr_voro, qs_env, mb_rho)
3514
3515 IF (dft_control%nspins > 1) THEN
3516 CALL auxbas_pw_pool%give_back_pw(mb_rho)
3517 DEALLOCATE (mb_rho)
3518 END IF
3519
3520 IF (unit_nr_voro > 0) THEN
3521 CALL cp_print_key_finished_output(unit_nr_voro, logger, input, "DFT%PRINT%VORONOI")
3522 END IF
3523
3524 END IF
3525 END IF
3526
3527 ! MAO analysis
3528 print_key => section_vals_get_subs_vals(input, "DFT%PRINT%MAO_ANALYSIS")
3529 IF (btest(cp_print_key_should_output(logger%iter_info, print_key), cp_p_file)) THEN
3530 unit_nr = cp_print_key_unit_nr(logger, input, "DFT%PRINT%MAO_ANALYSIS", extension=".mao", log_filename=.false.)
3531 CALL mao_analysis(qs_env, print_key, unit_nr)
3532 CALL cp_print_key_finished_output(unit_nr, logger, input, "DFT%PRINT%MAO_ANALYSIS")
3533 END IF
3534
3535 ! MINBAS analysis
3536 print_key => section_vals_get_subs_vals(input, "DFT%PRINT%MINBAS_ANALYSIS")
3537 IF (btest(cp_print_key_should_output(logger%iter_info, print_key), cp_p_file)) THEN
3538 unit_nr = cp_print_key_unit_nr(logger, input, "DFT%PRINT%MINBAS_ANALYSIS", extension=".mao", log_filename=.false.)
3539 CALL minbas_analysis(qs_env, print_key, unit_nr)
3540 CALL cp_print_key_finished_output(unit_nr, logger, input, "DFT%PRINT%MINBAS_ANALYSIS")
3541 END IF
3542
3543 ! IAO analysis
3544 print_key => section_vals_get_subs_vals(input, "DFT%PRINT%IAO_ANALYSIS")
3545 IF (btest(cp_print_key_should_output(logger%iter_info, print_key), cp_p_file)) THEN
3546 unit_nr = cp_print_key_unit_nr(logger, input, "DFT%PRINT%IAO_ANALYSIS", extension=".iao", log_filename=.false.)
3547 CALL iao_read_input(iao_env, print_key, cell)
3548 IF (particle_set(1)%fragment_index /= 0) iao_env%do_fragments = .true.
3549 IF (iao_env%do_iao) THEN
3550 CALL iao_wfn_analysis(qs_env, iao_env, unit_nr)
3551 END IF
3552 CALL cp_print_key_finished_output(unit_nr, logger, input, "DFT%PRINT%IAO_ANALYSIS")
3553 END IF
3554
3555 ! Energy Decomposition Analysis
3556 print_key => section_vals_get_subs_vals(input, "DFT%PRINT%ENERGY_DECOMPOSITION_ANALYSIS")
3557 IF (btest(cp_print_key_should_output(logger%iter_info, print_key), cp_p_file)) THEN
3558 unit_nr = cp_print_key_unit_nr(logger, input, "DFT%PRINT%ENERGY_DECOMPOSITION_ANALYSIS", &
3559 extension=".mao", log_filename=.false.)
3560 CALL edmf_analysis(qs_env, print_key, unit_nr)
3561 CALL cp_print_key_finished_output(unit_nr, logger, input, "DFT%PRINT%ENERGY_DECOMPOSITION_ANALYSIS")
3562 END IF
3563
3564 ! Print the density in the RI-HFX basis
3565 hfx_section => section_vals_get_subs_vals(input, "DFT%XC%HF")
3566 CALL section_vals_get(hfx_section, explicit=do_hfx)
3567 CALL section_vals_get(hfx_section, n_repetition=n_rep_hf)
3568 IF (do_hfx) THEN
3569 DO i = 1, n_rep_hf
3570 IF (qs_env%x_data(i, 1)%do_hfx_ri) CALL print_ri_hfx(qs_env%x_data(i, 1)%ri_data, qs_env)
3571 END DO
3572 END IF
3573
3574 DEALLOCATE (zcharge)
3575
3576 CALL timestop(handle)
3577
3578 END SUBROUTINE write_mo_free_results
3579
3580! **************************************************************************************************
3581!> \brief Calculates Hirshfeld charges
3582!> \param qs_env the qs_env where to calculate the charges
3583!> \param input_section the input section for Hirshfeld charges
3584!> \param unit_nr the output unit number
3585! **************************************************************************************************
3586 SUBROUTINE hirshfeld_charges(qs_env, input_section, unit_nr)
3587 TYPE(qs_environment_type), POINTER :: qs_env
3588 TYPE(section_vals_type), POINTER :: input_section
3589 INTEGER, INTENT(IN) :: unit_nr
3590
3591 INTEGER :: i, iat, ikind, natom, nkind, nspin, &
3592 radius_type, refc, shapef
3593 INTEGER, DIMENSION(:), POINTER :: atom_list
3594 LOGICAL :: do_radius, do_sc, paw_atom
3595 REAL(kind=dp) :: zeff
3596 REAL(kind=dp), DIMENSION(:), POINTER :: radii
3597 REAL(kind=dp), DIMENSION(:, :), POINTER :: charges
3598 TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
3599 TYPE(atomic_kind_type), POINTER :: atomic_kind
3600 TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: matrix_p, matrix_s
3601 TYPE(dft_control_type), POINTER :: dft_control
3602 TYPE(hirshfeld_type), POINTER :: hirshfeld_env
3603 TYPE(mp_para_env_type), POINTER :: para_env
3604 TYPE(mpole_rho_atom), DIMENSION(:), POINTER :: mp_rho
3605 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
3606 TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
3607 TYPE(qs_rho_type), POINTER :: rho
3608 TYPE(rho0_mpole_type), POINTER :: rho0_mpole
3609
3610 NULLIFY (hirshfeld_env)
3611 NULLIFY (radii)
3612 CALL create_hirshfeld_type(hirshfeld_env)
3613 !
3614 CALL get_qs_env(qs_env, nkind=nkind, natom=natom)
3615 ALLOCATE (hirshfeld_env%charges(natom))
3616 ! input options
3617 CALL section_vals_val_get(input_section, "SELF_CONSISTENT", l_val=do_sc)
3618 CALL section_vals_val_get(input_section, "USER_RADIUS", l_val=do_radius)
3619 CALL section_vals_val_get(input_section, "SHAPE_FUNCTION", i_val=shapef)
3620 CALL section_vals_val_get(input_section, "REFERENCE_CHARGE", i_val=refc)
3621 IF (do_radius) THEN
3622 radius_type = radius_user
3623 CALL section_vals_val_get(input_section, "ATOMIC_RADII", r_vals=radii)
3624 IF (.NOT. SIZE(radii) == nkind) THEN
3625 CALL cp_abort(__location__, &
3626 "Length of keyword HIRSHFELD\ATOMIC_RADII does not "// &
3627 "match number of atomic kinds in the input coordinate file.")
3628 END IF
3629 ELSE
3630 radius_type = radius_covalent
3631 END IF
3632 CALL set_hirshfeld_info(hirshfeld_env, shape_function_type=shapef, &
3633 iterative=do_sc, ref_charge=refc, &
3634 radius_type=radius_type)
3635 ! shape function
3636 CALL get_qs_env(qs_env, qs_kind_set=qs_kind_set, atomic_kind_set=atomic_kind_set)
3637 CALL create_shape_function(hirshfeld_env, qs_kind_set, atomic_kind_set, &
3638 radii_list=radii)
3639 ! reference charges
3640 CALL get_qs_env(qs_env, rho=rho)
3641 CALL qs_rho_get(rho, rho_ao_kp=matrix_p)
3642 nspin = SIZE(matrix_p, 1)
3643 ALLOCATE (charges(natom, nspin))
3644 SELECT CASE (refc)
3645 CASE (ref_charge_atomic)
3646 DO ikind = 1, nkind
3647 CALL get_qs_kind(qs_kind_set(ikind), zeff=zeff)
3648 atomic_kind => atomic_kind_set(ikind)
3649 CALL get_atomic_kind(atomic_kind, atom_list=atom_list)
3650 DO iat = 1, SIZE(atom_list)
3651 i = atom_list(iat)
3652 hirshfeld_env%charges(i) = zeff
3653 END DO
3654 END DO
3655 CASE (ref_charge_mulliken)
3656 CALL get_qs_env(qs_env, matrix_s_kp=matrix_s, para_env=para_env)
3657 CALL mulliken_charges(matrix_p, matrix_s, para_env, charges)
3658 DO iat = 1, natom
3659 hirshfeld_env%charges(iat) = sum(charges(iat, :))
3660 END DO
3661 CASE DEFAULT
3662 cpabort("Unknown type of reference charge for Hirshfeld partitioning.")
3663 END SELECT
3664 !
3665 charges = 0.0_dp
3666 IF (hirshfeld_env%iterative) THEN
3667 ! Hirshfeld-I charges
3668 CALL comp_hirshfeld_i_charges(qs_env, hirshfeld_env, charges, unit_nr)
3669 ELSE
3670 ! Hirshfeld charges
3671 CALL comp_hirshfeld_charges(qs_env, hirshfeld_env, charges)
3672 END IF
3673 CALL get_qs_env(qs_env, particle_set=particle_set, dft_control=dft_control)
3674 IF (dft_control%qs_control%gapw) THEN
3675 ! GAPW: add core charges (rho_hard - rho_soft)
3676 CALL get_qs_env(qs_env, rho0_mpole=rho0_mpole)
3677 CALL get_rho0_mpole(rho0_mpole, mp_rho=mp_rho)
3678 DO iat = 1, natom
3679 atomic_kind => particle_set(iat)%atomic_kind
3680 CALL get_atomic_kind(atomic_kind, kind_number=ikind)
3681 CALL get_qs_kind(qs_kind_set(ikind), paw_atom=paw_atom)
3682 IF (paw_atom) THEN
3683 charges(iat, 1:nspin) = charges(iat, 1:nspin) + mp_rho(iat)%q0(1:nspin)
3684 END IF
3685 END DO
3686 END IF
3687 !
3688 IF (unit_nr > 0) THEN
3689 CALL write_hirshfeld_charges(charges, hirshfeld_env, particle_set, &
3690 qs_kind_set, unit_nr)
3691 END IF
3692 ! Save the charges to the results under the tag [HIRSHFELD-CHARGES]
3693 CALL save_hirshfeld_charges(charges, particle_set, qs_kind_set, qs_env)
3694 !
3695 CALL release_hirshfeld_type(hirshfeld_env)
3696 DEALLOCATE (charges)
3697
3698 END SUBROUTINE hirshfeld_charges
3699
3700! **************************************************************************************************
3701!> \brief ...
3702!> \param ca ...
3703!> \param a ...
3704!> \param cb ...
3705!> \param b ...
3706!> \param l ...
3707! **************************************************************************************************
3708 SUBROUTINE project_function_a(ca, a, cb, b, l)
3709 ! project function cb on ca
3710 REAL(kind=dp), DIMENSION(:), INTENT(OUT) :: ca
3711 REAL(kind=dp), DIMENSION(:), INTENT(IN) :: a, cb, b
3712 INTEGER, INTENT(IN) :: l
3713
3714 INTEGER :: info, n
3715 INTEGER, ALLOCATABLE, DIMENSION(:) :: ipiv
3716 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :) :: smat, tmat, v
3717
3718 n = SIZE(ca)
3719 ALLOCATE (smat(n, n), tmat(n, n), v(n, 1), ipiv(n))
3720
3721 CALL sg_overlap(smat, l, a, a)
3722 CALL sg_overlap(tmat, l, a, b)
3723 v(:, 1) = matmul(tmat, cb)
3724 CALL dgesv(n, 1, smat, n, ipiv, v, n, info)
3725 cpassert(info == 0)
3726 ca(:) = v(:, 1)
3727
3728 DEALLOCATE (smat, tmat, v, ipiv)
3729
3730 END SUBROUTINE project_function_a
3731
3732! **************************************************************************************************
3733!> \brief ...
3734!> \param ca ...
3735!> \param a ...
3736!> \param bfun ...
3737!> \param grid_atom ...
3738!> \param l ...
3739! **************************************************************************************************
3740 SUBROUTINE project_function_b(ca, a, bfun, grid_atom, l)
3741 ! project function f on ca
3742 REAL(kind=dp), DIMENSION(:), INTENT(OUT) :: ca
3743 REAL(kind=dp), DIMENSION(:), INTENT(IN) :: a, bfun
3744 TYPE(grid_atom_type), POINTER :: grid_atom
3745 INTEGER, INTENT(IN) :: l
3746
3747 INTEGER :: i, info, n, nr
3748 INTEGER, ALLOCATABLE, DIMENSION(:) :: ipiv
3749 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: afun
3750 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :) :: smat, v
3751
3752 n = SIZE(ca)
3753 nr = grid_atom%nr
3754 ALLOCATE (smat(n, n), v(n, 1), ipiv(n), afun(nr))
3755
3756 CALL sg_overlap(smat, l, a, a)
3757 DO i = 1, n
3758 afun(:) = grid_atom%rad(:)**l*exp(-a(i)*grid_atom%rad2(:))
3759 v(i, 1) = sum(afun(:)*bfun(:)*grid_atom%wr(:))
3760 END DO
3761 CALL dgesv(n, 1, smat, n, ipiv, v, n, info)
3762 cpassert(info == 0)
3763 ca(:) = v(:, 1)
3764
3765 DEALLOCATE (smat, v, ipiv, afun)
3766
3767 END SUBROUTINE project_function_b
3768
3769! **************************************************************************************************
3770!> \brief Performs printing of cube files from local energy
3771!> \param input input
3772!> \param logger the logger
3773!> \param qs_env the qs_env in which the qs_env lives
3774!> \par History
3775!> 07.2019 created
3776!> \author JGH
3777! **************************************************************************************************
3778 SUBROUTINE qs_scf_post_local_energy(input, logger, qs_env)
3779 TYPE(section_vals_type), POINTER :: input
3780 TYPE(cp_logger_type), POINTER :: logger
3781 TYPE(qs_environment_type), POINTER :: qs_env
3782
3783 CHARACTER(len=*), PARAMETER :: routinen = 'qs_scf_post_local_energy'
3784
3785 CHARACTER(LEN=default_path_length) :: filename, my_pos_cube
3786 INTEGER :: handle, io_unit, natom, unit_nr
3787 LOGICAL :: append_cube, gapw, gapw_xc, mpi_io
3788 TYPE(dft_control_type), POINTER :: dft_control
3789 TYPE(particle_list_type), POINTER :: particles
3790 TYPE(pw_env_type), POINTER :: pw_env
3791 TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
3792 TYPE(pw_r3d_rs_type) :: eden
3793 TYPE(qs_subsys_type), POINTER :: subsys
3794 TYPE(section_vals_type), POINTER :: dft_section
3795
3796 CALL timeset(routinen, handle)
3797 io_unit = cp_logger_get_default_io_unit(logger)
3798 IF (btest(cp_print_key_should_output(logger%iter_info, input, &
3799 "DFT%PRINT%LOCAL_ENERGY_CUBE"), cp_p_file)) THEN
3800 dft_section => section_vals_get_subs_vals(input, "DFT")
3801 CALL get_qs_env(qs_env=qs_env, dft_control=dft_control, natom=natom)
3802 gapw = dft_control%qs_control%gapw
3803 gapw_xc = dft_control%qs_control%gapw_xc
3804 CALL get_qs_env(qs_env=qs_env, pw_env=pw_env, subsys=subsys)
3805 CALL qs_subsys_get(subsys, particles=particles)
3806 CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool)
3807 CALL auxbas_pw_pool%create_pw(eden)
3808 !
3809 CALL qs_local_energy(qs_env, eden)
3810 !
3811 append_cube = section_get_lval(input, "DFT%PRINT%LOCAL_ENERGY_CUBE%APPEND")
3812 IF (append_cube) THEN
3813 my_pos_cube = "APPEND"
3814 ELSE
3815 my_pos_cube = "REWIND"
3816 END IF
3817 mpi_io = .true.
3818 unit_nr = cp_print_key_unit_nr(logger, input, "DFT%PRINT%LOCAL_ENERGY_CUBE", &
3819 extension=".cube", middle_name="local_energy", &
3820 file_position=my_pos_cube, mpi_io=mpi_io)
3821 CALL cp_pw_to_cube(eden, unit_nr, "LOCAL ENERGY", particles=particles, &
3822 stride=section_get_ivals(dft_section, "PRINT%LOCAL_ENERGY_CUBE%STRIDE"), &
3823 max_file_size_mb=section_get_rval(dft_section, "PRINT%LOCAL_ENERGY_CUBE%MAX_FILE_SIZE_MB"), &
3824 mpi_io=mpi_io)
3825 IF (io_unit > 0) THEN
3826 INQUIRE (unit=unit_nr, name=filename)
3827 IF (gapw .OR. gapw_xc) THEN
3828 WRITE (unit=io_unit, fmt="(/,T3,A,A)") &
3829 "The soft part of the local energy is written to the file: ", trim(adjustl(filename))
3830 ELSE
3831 WRITE (unit=io_unit, fmt="(/,T3,A,A)") &
3832 "The local energy is written to the file: ", trim(adjustl(filename))
3833 END IF
3834 END IF
3835 CALL cp_print_key_finished_output(unit_nr, logger, input, &
3836 "DFT%PRINT%LOCAL_ENERGY_CUBE", mpi_io=mpi_io)
3837 !
3838 CALL auxbas_pw_pool%give_back_pw(eden)
3839 END IF
3840 CALL timestop(handle)
3841
3842 END SUBROUTINE qs_scf_post_local_energy
3843
3844! **************************************************************************************************
3845!> \brief Performs printing of cube files from local energy
3846!> \param input input
3847!> \param logger the logger
3848!> \param qs_env the qs_env in which the qs_env lives
3849!> \par History
3850!> 07.2019 created
3851!> \author JGH
3852! **************************************************************************************************
3853 SUBROUTINE qs_scf_post_local_stress(input, logger, qs_env)
3854 TYPE(section_vals_type), POINTER :: input
3855 TYPE(cp_logger_type), POINTER :: logger
3856 TYPE(qs_environment_type), POINTER :: qs_env
3857
3858 CHARACTER(len=*), PARAMETER :: routinen = 'qs_scf_post_local_stress'
3859
3860 CHARACTER(LEN=default_path_length) :: filename, my_pos_cube
3861 INTEGER :: handle, io_unit, natom, unit_nr
3862 LOGICAL :: append_cube, gapw, gapw_xc, mpi_io
3863 REAL(kind=dp) :: beta
3864 TYPE(dft_control_type), POINTER :: dft_control
3865 TYPE(particle_list_type), POINTER :: particles
3866 TYPE(pw_env_type), POINTER :: pw_env
3867 TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
3868 TYPE(pw_r3d_rs_type) :: stress
3869 TYPE(qs_subsys_type), POINTER :: subsys
3870 TYPE(section_vals_type), POINTER :: dft_section
3871
3872 CALL timeset(routinen, handle)
3873 io_unit = cp_logger_get_default_io_unit(logger)
3874 IF (btest(cp_print_key_should_output(logger%iter_info, input, &
3875 "DFT%PRINT%LOCAL_STRESS_CUBE"), cp_p_file)) THEN
3876 CALL cp_warn(__location__, &
3877 "LOCAL_STRESS_CUBE uses the existing experimental local stress implementation")
3878 dft_section => section_vals_get_subs_vals(input, "DFT")
3879 CALL get_qs_env(qs_env=qs_env, dft_control=dft_control, natom=natom)
3880 gapw = dft_control%qs_control%gapw
3881 gapw_xc = dft_control%qs_control%gapw_xc
3882 CALL get_qs_env(qs_env=qs_env, pw_env=pw_env, subsys=subsys)
3883 CALL qs_subsys_get(subsys, particles=particles)
3884 CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool)
3885 CALL auxbas_pw_pool%create_pw(stress)
3886 !
3887 ! use beta=0: kinetic energy density in symmetric form
3888 beta = 0.0_dp
3889 CALL qs_local_stress(qs_env, beta=beta)
3890 !
3891 append_cube = section_get_lval(input, "DFT%PRINT%LOCAL_STRESS_CUBE%APPEND")
3892 IF (append_cube) THEN
3893 my_pos_cube = "APPEND"
3894 ELSE
3895 my_pos_cube = "REWIND"
3896 END IF
3897 mpi_io = .true.
3898 unit_nr = cp_print_key_unit_nr(logger, input, "DFT%PRINT%LOCAL_STRESS_CUBE", &
3899 extension=".cube", middle_name="local_stress", &
3900 file_position=my_pos_cube, mpi_io=mpi_io)
3901 CALL cp_pw_to_cube(stress, unit_nr, "LOCAL STRESS", particles=particles, &
3902 stride=section_get_ivals(dft_section, "PRINT%LOCAL_STRESS_CUBE%STRIDE"), &
3903 max_file_size_mb=section_get_rval(dft_section, "PRINT%LOCAL_STRESS_CUBE%MAX_FILE_SIZE_MB"), &
3904 mpi_io=mpi_io)
3905 IF (io_unit > 0) THEN
3906 INQUIRE (unit=unit_nr, name=filename)
3907 WRITE (unit=io_unit, fmt="(/,T3,A)") "Write 1/3*Tr(sigma) to cube file"
3908 IF (gapw .OR. gapw_xc) THEN
3909 WRITE (unit=io_unit, fmt="(T3,A,A)") &
3910 "The soft part of the local stress is written to the file: ", trim(adjustl(filename))
3911 ELSE
3912 WRITE (unit=io_unit, fmt="(T3,A,A)") &
3913 "The local stress is written to the file: ", trim(adjustl(filename))
3914 END IF
3915 END IF
3916 CALL cp_print_key_finished_output(unit_nr, logger, input, &
3917 "DFT%PRINT%LOCAL_STRESS_CUBE", mpi_io=mpi_io)
3918 !
3919 CALL auxbas_pw_pool%give_back_pw(stress)
3920 END IF
3921
3922 CALL timestop(handle)
3923
3924 END SUBROUTINE qs_scf_post_local_stress
3925
3926! **************************************************************************************************
3927!> \brief Performs printing of cube files related to the implicit Poisson solver
3928!> \param input input
3929!> \param logger the logger
3930!> \param qs_env the qs_env in which the qs_env lives
3931!> \par History
3932!> 03.2016 refactored from write_mo_free_results [Hossein Bani-Hashemian]
3933!> \author Mohammad Hossein Bani-Hashemian
3934! **************************************************************************************************
3935 SUBROUTINE qs_scf_post_ps_implicit(input, logger, qs_env)
3936 TYPE(section_vals_type), POINTER :: input
3937 TYPE(cp_logger_type), POINTER :: logger
3938 TYPE(qs_environment_type), POINTER :: qs_env
3939
3940 CHARACTER(len=*), PARAMETER :: routinen = 'qs_scf_post_ps_implicit'
3941
3942 CHARACTER(LEN=default_path_length) :: filename, my_pos_cube
3943 INTEGER :: boundary_condition, handle, i, j, &
3944 n_cstr, n_tiles, unit_nr
3945 LOGICAL :: append_cube, do_cstr_charge_cube, do_dielectric_cube, do_dirichlet_bc_cube, &
3946 has_dirichlet_bc, has_implicit_ps, mpi_io, tile_cubes
3947 TYPE(particle_list_type), POINTER :: particles
3948 TYPE(pw_env_type), POINTER :: pw_env
3949 TYPE(pw_poisson_type), POINTER :: poisson_env
3950 TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
3951 TYPE(pw_r3d_rs_type) :: aux_r
3952 TYPE(pw_r3d_rs_type), POINTER :: dirichlet_tile
3953 TYPE(qs_subsys_type), POINTER :: subsys
3954 TYPE(section_vals_type), POINTER :: dft_section
3955
3956 CALL timeset(routinen, handle)
3957
3958 NULLIFY (pw_env, auxbas_pw_pool, dft_section, particles)
3959
3960 dft_section => section_vals_get_subs_vals(input, "DFT")
3961 CALL get_qs_env(qs_env=qs_env, pw_env=pw_env, subsys=subsys)
3962 CALL qs_subsys_get(subsys, particles=particles)
3963 CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool)
3964
3965 has_implicit_ps = .false.
3966 CALL get_qs_env(qs_env=qs_env, pw_env=pw_env)
3967 IF (pw_env%poisson_env%parameters%solver == pw_poisson_implicit) has_implicit_ps = .true.
3968
3969 ! Write the dielectric constant into a cube file
3970 do_dielectric_cube = btest(cp_print_key_should_output(logger%iter_info, input, &
3971 "DFT%PRINT%IMPLICIT_PSOLVER%DIELECTRIC_CUBE"), cp_p_file)
3972 IF (has_implicit_ps .AND. do_dielectric_cube) THEN
3973 append_cube = section_get_lval(input, "DFT%PRINT%IMPLICIT_PSOLVER%DIELECTRIC_CUBE%APPEND")
3974 my_pos_cube = "REWIND"
3975 IF (append_cube) THEN
3976 my_pos_cube = "APPEND"
3977 END IF
3978 mpi_io = .true.
3979 unit_nr = cp_print_key_unit_nr(logger, input, "DFT%PRINT%IMPLICIT_PSOLVER%DIELECTRIC_CUBE", &
3980 extension=".cube", middle_name="DIELECTRIC_CONSTANT", file_position=my_pos_cube, &
3981 mpi_io=mpi_io)
3982 CALL pw_env_get(pw_env, poisson_env=poisson_env, auxbas_pw_pool=auxbas_pw_pool)
3983 CALL auxbas_pw_pool%create_pw(aux_r)
3984
3985 boundary_condition = pw_env%poisson_env%parameters%ps_implicit_params%boundary_condition
3986 SELECT CASE (boundary_condition)
3988 CALL pw_copy(poisson_env%implicit_env%dielectric%eps, aux_r)
3989 CASE (mixed_bc, neumann_bc)
3990 CALL pw_shrink(pw_env%poisson_env%parameters%ps_implicit_params%neumann_directions, &
3991 pw_env%poisson_env%implicit_env%dct_env%dests_shrink, &
3992 pw_env%poisson_env%implicit_env%dct_env%srcs_shrink, &
3993 pw_env%poisson_env%implicit_env%dct_env%bounds_local_shftd, &
3994 poisson_env%implicit_env%dielectric%eps, aux_r)
3995 END SELECT
3996
3997 CALL cp_pw_to_cube(aux_r, unit_nr, "DIELECTRIC CONSTANT", particles=particles, &
3998 stride=section_get_ivals(dft_section, "PRINT%IMPLICIT_PSOLVER%DIELECTRIC_CUBE%STRIDE"), &
3999 max_file_size_mb=section_get_rval(dft_section, "PRINT%IMPLICIT_PSOLVER%DIELECTRIC_CUBE%MAX_FILE_SIZE_MB"), &
4000 mpi_io=mpi_io)
4001 CALL cp_print_key_finished_output(unit_nr, logger, input, &
4002 "DFT%PRINT%IMPLICIT_PSOLVER%DIELECTRIC_CUBE", mpi_io=mpi_io)
4003
4004 CALL auxbas_pw_pool%give_back_pw(aux_r)
4005 END IF
4006
4007 ! Write Dirichlet constraint charges into a cube file
4008 do_cstr_charge_cube = btest(cp_print_key_should_output(logger%iter_info, input, &
4009 "DFT%PRINT%IMPLICIT_PSOLVER%DIRICHLET_CSTR_CHARGE_CUBE"), cp_p_file)
4010
4011 has_dirichlet_bc = .false.
4012 IF (has_implicit_ps) THEN
4013 boundary_condition = pw_env%poisson_env%parameters%ps_implicit_params%boundary_condition
4014 IF (boundary_condition == mixed_periodic_bc .OR. boundary_condition == mixed_bc) THEN
4015 has_dirichlet_bc = .true.
4016 END IF
4017 END IF
4018
4019 IF (has_implicit_ps .AND. do_cstr_charge_cube .AND. has_dirichlet_bc) THEN
4020 append_cube = section_get_lval(input, &
4021 "DFT%PRINT%IMPLICIT_PSOLVER%DIRICHLET_CSTR_CHARGE_CUBE%APPEND")
4022 my_pos_cube = "REWIND"
4023 IF (append_cube) THEN
4024 my_pos_cube = "APPEND"
4025 END IF
4026 mpi_io = .true.
4027 unit_nr = cp_print_key_unit_nr(logger, input, &
4028 "DFT%PRINT%IMPLICIT_PSOLVER%DIRICHLET_CSTR_CHARGE_CUBE", &
4029 extension=".cube", middle_name="dirichlet_cstr_charge", file_position=my_pos_cube, &
4030 mpi_io=mpi_io)
4031 CALL pw_env_get(pw_env, poisson_env=poisson_env, auxbas_pw_pool=auxbas_pw_pool)
4032 CALL auxbas_pw_pool%create_pw(aux_r)
4033
4034 boundary_condition = pw_env%poisson_env%parameters%ps_implicit_params%boundary_condition
4035 SELECT CASE (boundary_condition)
4036 CASE (mixed_periodic_bc)
4037 CALL pw_copy(poisson_env%implicit_env%cstr_charge, aux_r)
4038 CASE (mixed_bc)
4039 CALL pw_shrink(pw_env%poisson_env%parameters%ps_implicit_params%neumann_directions, &
4040 pw_env%poisson_env%implicit_env%dct_env%dests_shrink, &
4041 pw_env%poisson_env%implicit_env%dct_env%srcs_shrink, &
4042 pw_env%poisson_env%implicit_env%dct_env%bounds_local_shftd, &
4043 poisson_env%implicit_env%cstr_charge, aux_r)
4044 END SELECT
4045
4046 CALL cp_pw_to_cube(aux_r, unit_nr, "DIRICHLET CONSTRAINT CHARGE", particles=particles, &
4047 stride=section_get_ivals(dft_section, "PRINT%IMPLICIT_PSOLVER%DIRICHLET_CSTR_CHARGE_CUBE%STRIDE"), &
4048 max_file_size_mb=section_get_rval(dft_section, "PRINT%IMPLICIT_PSOLVER%DIRICHLET_CSTR_CHARGE_CUBE%MAX_FILE_SIZE_MB"), &
4049 mpi_io=mpi_io)
4050 CALL cp_print_key_finished_output(unit_nr, logger, input, &
4051 "DFT%PRINT%IMPLICIT_PSOLVER%DIRICHLET_CSTR_CHARGE_CUBE", mpi_io=mpi_io)
4052
4053 CALL auxbas_pw_pool%give_back_pw(aux_r)
4054 END IF
4055
4056 ! Write Dirichlet type constranits into cube files
4057 do_dirichlet_bc_cube = btest(cp_print_key_should_output(logger%iter_info, input, &
4058 "DFT%PRINT%IMPLICIT_PSOLVER%DIRICHLET_BC_CUBE"), cp_p_file)
4059 has_dirichlet_bc = .false.
4060 IF (has_implicit_ps) THEN
4061 boundary_condition = pw_env%poisson_env%parameters%ps_implicit_params%boundary_condition
4062 IF (boundary_condition == mixed_periodic_bc .OR. boundary_condition == mixed_bc) THEN
4063 has_dirichlet_bc = .true.
4064 END IF
4065 END IF
4066
4067 IF (has_implicit_ps .AND. has_dirichlet_bc .AND. do_dirichlet_bc_cube) THEN
4068 append_cube = section_get_lval(input, "DFT%PRINT%IMPLICIT_PSOLVER%DIRICHLET_BC_CUBE%APPEND")
4069 my_pos_cube = "REWIND"
4070 IF (append_cube) THEN
4071 my_pos_cube = "APPEND"
4072 END IF
4073 tile_cubes = section_get_lval(input, "DFT%PRINT%IMPLICIT_PSOLVER%DIRICHLET_BC_CUBE%TILE_CUBES")
4074
4075 CALL pw_env_get(pw_env, poisson_env=poisson_env, auxbas_pw_pool=auxbas_pw_pool)
4076 CALL auxbas_pw_pool%create_pw(aux_r)
4077 CALL pw_zero(aux_r)
4078
4079 IF (tile_cubes) THEN
4080 ! one cube file per tile
4081 n_cstr = SIZE(poisson_env%implicit_env%contacts)
4082 DO j = 1, n_cstr
4083 n_tiles = poisson_env%implicit_env%contacts(j)%dirichlet_bc%n_tiles
4084 DO i = 1, n_tiles
4085 filename = "dirichlet_cstr_"//trim(adjustl(cp_to_string(j)))// &
4086 "_tile_"//trim(adjustl(cp_to_string(i)))
4087 mpi_io = .true.
4088 unit_nr = cp_print_key_unit_nr(logger, input, "DFT%PRINT%IMPLICIT_PSOLVER%DIRICHLET_BC_CUBE", &
4089 extension=".cube", middle_name=filename, file_position=my_pos_cube, &
4090 mpi_io=mpi_io)
4091
4092 CALL pw_copy(poisson_env%implicit_env%contacts(j)%dirichlet_bc%tiles(i)%tile%tile_pw, aux_r)
4093
4094 CALL cp_pw_to_cube(aux_r, unit_nr, "DIRICHLET TYPE CONSTRAINT", particles=particles, &
4095 stride=section_get_ivals(dft_section, "PRINT%IMPLICIT_PSOLVER%DIRICHLET_BC_CUBE%STRIDE"), &
4096 max_file_size_mb=section_get_rval(dft_section, "PRINT%IMPLICIT_PSOLVER%DIRICHLET_BC_CUBE%MAX_FILE_SIZE_MB"), &
4097 mpi_io=mpi_io)
4098 CALL cp_print_key_finished_output(unit_nr, logger, input, &
4099 "DFT%PRINT%IMPLICIT_PSOLVER%DIRICHLET_BC_CUBE", mpi_io=mpi_io)
4100 END DO
4101 END DO
4102 ELSE
4103 ! a single cube file
4104 NULLIFY (dirichlet_tile)
4105 ALLOCATE (dirichlet_tile)
4106 CALL auxbas_pw_pool%create_pw(dirichlet_tile)
4107 CALL pw_zero(dirichlet_tile)
4108 mpi_io = .true.
4109 unit_nr = cp_print_key_unit_nr(logger, input, "DFT%PRINT%IMPLICIT_PSOLVER%DIRICHLET_BC_CUBE", &
4110 extension=".cube", middle_name="DIRICHLET_CSTR", file_position=my_pos_cube, &
4111 mpi_io=mpi_io)
4112
4113 n_cstr = SIZE(poisson_env%implicit_env%contacts)
4114 DO j = 1, n_cstr
4115 n_tiles = poisson_env%implicit_env%contacts(j)%dirichlet_bc%n_tiles
4116 DO i = 1, n_tiles
4117 CALL pw_copy(poisson_env%implicit_env%contacts(j)%dirichlet_bc%tiles(i)%tile%tile_pw, dirichlet_tile)
4118 CALL pw_axpy(dirichlet_tile, aux_r)
4119 END DO
4120 END DO
4121
4122 CALL cp_pw_to_cube(aux_r, unit_nr, "DIRICHLET TYPE CONSTRAINT", particles=particles, &
4123 stride=section_get_ivals(dft_section, "PRINT%IMPLICIT_PSOLVER%DIRICHLET_BC_CUBE%STRIDE"), &
4124 max_file_size_mb=section_get_rval(dft_section, "PRINT%IMPLICIT_PSOLVER%DIRICHLET_BC_CUBE%MAX_FILE_SIZE_MB"), &
4125 mpi_io=mpi_io)
4126 CALL cp_print_key_finished_output(unit_nr, logger, input, &
4127 "DFT%PRINT%IMPLICIT_PSOLVER%DIRICHLET_BC_CUBE", mpi_io=mpi_io)
4128 CALL auxbas_pw_pool%give_back_pw(dirichlet_tile)
4129 DEALLOCATE (dirichlet_tile)
4130 END IF
4131
4132 CALL auxbas_pw_pool%give_back_pw(aux_r)
4133 END IF
4134
4135 CALL timestop(handle)
4136
4137 END SUBROUTINE qs_scf_post_ps_implicit
4138
4139!**************************************************************************************************
4140!> \brief write an adjacency (interaction) matrix
4141!> \param qs_env qs environment
4142!> \param input the input
4143!> \author Mohammad Hossein Bani-Hashemian
4144! **************************************************************************************************
4145 SUBROUTINE write_adjacency_matrix(qs_env, input)
4146 TYPE(qs_environment_type), POINTER :: qs_env
4147 TYPE(section_vals_type), POINTER :: input
4148
4149 CHARACTER(len=*), PARAMETER :: routinen = 'write_adjacency_matrix'
4150
4151 INTEGER :: adjm_size, colind, handle, iatom, ikind, &
4152 ind, jatom, jkind, k, natom, nkind, &
4153 output_unit, rowind, unit_nr
4154 INTEGER, ALLOCATABLE, DIMENSION(:) :: interact_adjm
4155 LOGICAL :: do_adjm_write, do_symmetric
4156 TYPE(cp_logger_type), POINTER :: logger
4157 TYPE(gto_basis_set_p_type), DIMENSION(:), POINTER :: basis_set_list_a, basis_set_list_b
4158 TYPE(gto_basis_set_type), POINTER :: basis_set_a, basis_set_b
4159 TYPE(mp_para_env_type), POINTER :: para_env
4161 DIMENSION(:), POINTER :: nl_iterator
4162 TYPE(neighbor_list_set_p_type), DIMENSION(:), &
4163 POINTER :: nl
4164 TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
4165 TYPE(section_vals_type), POINTER :: dft_section
4166
4167 CALL timeset(routinen, handle)
4168
4169 NULLIFY (dft_section)
4170
4171 logger => cp_get_default_logger()
4172 output_unit = cp_logger_get_default_io_unit(logger)
4173
4174 dft_section => section_vals_get_subs_vals(input, "DFT")
4175 do_adjm_write = btest(cp_print_key_should_output(logger%iter_info, dft_section, &
4176 "PRINT%ADJMAT_WRITE"), cp_p_file)
4177
4178 IF (do_adjm_write) THEN
4179 NULLIFY (qs_kind_set, nl_iterator)
4180 NULLIFY (basis_set_list_a, basis_set_list_b, basis_set_a, basis_set_b)
4181
4182 CALL get_qs_env(qs_env, qs_kind_set=qs_kind_set, sab_orb=nl, natom=natom, para_env=para_env)
4183
4184 nkind = SIZE(qs_kind_set)
4185 cpassert(SIZE(nl) > 0)
4186 CALL get_neighbor_list_set_p(neighbor_list_sets=nl, symmetric=do_symmetric)
4187 cpassert(do_symmetric)
4188 ALLOCATE (basis_set_list_a(nkind), basis_set_list_b(nkind))
4189 CALL basis_set_list_setup(basis_set_list_a, "ORB", qs_kind_set)
4190 CALL basis_set_list_setup(basis_set_list_b, "ORB", qs_kind_set)
4191
4192 adjm_size = ((natom + 1)*natom)/2
4193 ALLOCATE (interact_adjm(4*adjm_size))
4194 interact_adjm = 0
4195
4196 NULLIFY (nl_iterator)
4197 CALL neighbor_list_iterator_create(nl_iterator, nl)
4198 DO WHILE (neighbor_list_iterate(nl_iterator) == 0)
4199 CALL get_iterator_info(nl_iterator, &
4200 ikind=ikind, jkind=jkind, &
4201 iatom=iatom, jatom=jatom)
4202
4203 basis_set_a => basis_set_list_a(ikind)%gto_basis_set
4204 IF (.NOT. ASSOCIATED(basis_set_a)) cycle
4205 basis_set_b => basis_set_list_b(jkind)%gto_basis_set
4206 IF (.NOT. ASSOCIATED(basis_set_b)) cycle
4207
4208 ! move everything to the upper triangular part
4209 IF (iatom <= jatom) THEN
4210 rowind = iatom
4211 colind = jatom
4212 ELSE
4213 rowind = jatom
4214 colind = iatom
4215 ! swap the kinds too
4216 ikind = ikind + jkind
4217 jkind = ikind - jkind
4218 ikind = ikind - jkind
4219 END IF
4220
4221 ! indexing upper triangular matrix
4222 ind = adjm_size - (natom - rowind + 1)*((natom - rowind + 1) + 1)/2 + colind - rowind + 1
4223 ! convert the upper triangular matrix into a adjm_size x 4 matrix
4224 ! columns are: iatom, jatom, ikind, jkind
4225 interact_adjm((ind - 1)*4 + 1) = rowind
4226 interact_adjm((ind - 1)*4 + 2) = colind
4227 interact_adjm((ind - 1)*4 + 3) = ikind
4228 interact_adjm((ind - 1)*4 + 4) = jkind
4229 END DO
4230
4231 CALL para_env%sum(interact_adjm)
4232
4233 unit_nr = cp_print_key_unit_nr(logger, dft_section, "PRINT%ADJMAT_WRITE", &
4234 extension=".adjmat", file_form="FORMATTED", &
4235 file_status="REPLACE")
4236 IF (unit_nr > 0) THEN
4237 WRITE (unit_nr, "(1A,2X,1A,5X,1A,4X,A5,3X,A5)") "#", "iatom", "jatom", "ikind", "jkind"
4238 DO k = 1, 4*adjm_size, 4
4239 ! print only the interacting atoms
4240 IF (interact_adjm(k) > 0 .AND. interact_adjm(k + 1) > 0) THEN
4241 WRITE (unit_nr, "(I8,2X,I8,3X,I6,2X,I6)") interact_adjm(k:k + 3)
4242 END IF
4243 END DO
4244 END IF
4245
4246 CALL cp_print_key_finished_output(unit_nr, logger, dft_section, "PRINT%ADJMAT_WRITE")
4247
4248 CALL neighbor_list_iterator_release(nl_iterator)
4249 DEALLOCATE (basis_set_list_a, basis_set_list_b)
4250 END IF
4251
4252 CALL timestop(handle)
4253
4254 END SUBROUTINE write_adjacency_matrix
4255
4256! **************************************************************************************************
4257!> \brief Updates Hartree potential with MP2 density. Important for REPEAT charges
4258!> \param rho ...
4259!> \param qs_env ...
4260!> \author Vladimir Rybkin
4261! **************************************************************************************************
4262 SUBROUTINE update_hartree_with_mp2(rho, qs_env)
4263 TYPE(qs_rho_type), POINTER :: rho
4264 TYPE(qs_environment_type), POINTER :: qs_env
4265
4266 LOGICAL :: use_virial
4267 TYPE(pw_c1d_gs_type) :: rho_tot_gspace, v_hartree_gspace
4268 TYPE(pw_c1d_gs_type), POINTER :: rho_core
4269 TYPE(pw_env_type), POINTER :: pw_env
4270 TYPE(pw_poisson_type), POINTER :: poisson_env
4271 TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
4272 TYPE(pw_r3d_rs_type), POINTER :: v_hartree_rspace
4273 TYPE(qs_energy_type), POINTER :: energy
4274 TYPE(virial_type), POINTER :: virial
4275
4276 NULLIFY (auxbas_pw_pool, pw_env, poisson_env, energy, rho_core, v_hartree_rspace, virial)
4277 CALL get_qs_env(qs_env, pw_env=pw_env, energy=energy, &
4278 rho_core=rho_core, virial=virial, &
4279 v_hartree_rspace=v_hartree_rspace)
4280
4281 use_virial = virial%pv_availability .AND. (.NOT. virial%pv_numer)
4282
4283 IF (.NOT. use_virial) THEN
4284
4285 CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool, &
4286 poisson_env=poisson_env)
4287 CALL auxbas_pw_pool%create_pw(v_hartree_gspace)
4288 CALL auxbas_pw_pool%create_pw(rho_tot_gspace)
4289
4290 CALL calc_rho_tot_gspace(rho_tot_gspace, qs_env, rho)
4291 CALL pw_poisson_solve(poisson_env, rho_tot_gspace, energy%hartree, &
4292 v_hartree_gspace, rho_core=rho_core)
4293
4294 CALL pw_transfer(v_hartree_gspace, v_hartree_rspace)
4295 CALL pw_scale(v_hartree_rspace, v_hartree_rspace%pw_grid%dvol)
4296
4297 CALL auxbas_pw_pool%give_back_pw(v_hartree_gspace)
4298 CALL auxbas_pw_pool%give_back_pw(rho_tot_gspace)
4299 END IF
4300
4301 END SUBROUTINE update_hartree_with_mp2
4302
4303END 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.
Writer for CASINO gwfn.data files.
subroutine, public write_casino(qs_env, casino_section)
Write a CASINO gwfn.data file from the converged GPW/GAPW wavefunction.
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, cartesian_basis)
...
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:245
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, 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...
subroutine, public cp_openpmd_close_iterations()
integer function, public cp_openpmd_print_key_unit_nr(logger, basis_section, print_key_path, middle_name, ignore_should_output, mpi_io, fout, openpmd_basename, openpmd_unit_dimension, openpmd_unit_si, sim_time)
...
subroutine, public cp_openpmd_print_key_finished_output(unit_nr, logger, basis_section, print_key_path, local, ignore_should_output, mpi_io)
should be called after you finish working with a unit obtained with cp_openpmd_print_key_unit_nr,...
routines to handle the output, The idea is to remove the decision of wheter to output and what to out...
character(len=default_string_length) function, public cp_iter_string(iter_info, print_key, for_file)
returns the iteration string, a string that is useful to create unique filenames (once you trim it)
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)
...
A wrapper around pw_to_openpmd() which accepts particle_list_type.
subroutine, public cp_pw_to_openpmd(pw, unit_nr, title, particles, zeff, stride, zero_tails, silent, mpi_io)
...
set of type/routines to handle the storage of results in force_envs
set of type/routines to handle the storage of results in force_envs
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:127
Definition and initialisation of the et_coupling data type.
subroutine, public set_et_coupling_type(et_coupling, et_mo_coeff, rest_mat)
...
GAPW reciprocal-space reconstruction and its discrete adjoint.
subroutine, public calculate_rhotot_elec_gspace(qs_env, auxbas_pw_pool, rhotot_elec_gspace, q_max, rho_hard, rho_soft, fsign, compute_tau, rho_source, allow_nonorthorhombic)
The total electronic density in reciprocal space (g-space) is calculated.
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:148
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 moments_format_trajectory
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
K-point MO wavefunction dump to TEXT file for post-processing (PDOS, etc.)
subroutine, public write_kpoint_mo_data(qs_env, print_section)
Write k-point resolved MO data to formatted text file.
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
Routines for the calculation of moments from Wannier functions.
subroutine, public calculate_kg_moments(qs_env, unit_nr, max_moment, magnetic, vel_reprs, com_nl)
Calculates multipole moments per molecule from the Kim-Gordon AO density matrix.
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, cell, unoccupied_orbs, unoccupied_evals, qs_env, calc_energies)
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 a_bohr
Definition physcon.F:136
real(kind=dp), parameter, public evolt
Definition physcon.F:183
real(kind=dp), parameter, public angstrom
Definition physcon.F:144
real(kind=dp), parameter, public debye
Definition physcon.F:201
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)
...
container for information about total charges on the grids
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.
Utilities for broadened DOS and PDOS output.
subroutine, public get_dos_pdos_flags(dos_section, do_dos_output, do_projected_dos, do_pdos, do_curve)
Resolve projected-DOS requests from a DOS print section.
Calculation and writing of density of states.
Definition qs_dos.F:14
subroutine, public calculate_dos_kp(qs_env, dft_section, write_curve_output)
Compute and write density of states (kpoints)
Definition qs_dos.F:364
subroutine, public calculate_dos(mos, dft_section, unoccupied_evals, smearing_enabled, write_curve_output)
Compute and write density of states.
Definition qs_dos.F:67
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, matrix_vhxc, rho, rho_xc, pw_env, ewald_env, ewald_pw, active_space, mpools, input, para_env, blacs_env, scf_control, rel_control, kinetic, qs_charges, vppl, xcint_weights, rho_core, rho_nlcc, rho_nlcc_g, ks_env, ks_qmmm_env, wf_history, scf_env, local_particles, local_molecules, distribution_2d, dbcsr_dist, molecule_kind_set, molecule_set, subsys, cp_subsys, oce, local_rho_set, rho_atom_set, task_list, task_list_soft, rho0_atom_set, rho0_mpole, rhoz_set, rhoz_cneo_set, ecoul_1c, rho0_s_rs, rho0_s_gs, rhoz_cneo_s_rs, rhoz_cneo_s_gs, do_kpoints, has_unit_metric, requires_mo_derivs, mo_derivs, mo_loc_history, nkind, natom, nelectron_total, nelectron_spin, efield, neighbor_list_id, linres_control, xas_env, virial, cp_ddapc_env, cp_ddapc_ewald, outer_scf_history, outer_scf_ihistory, x_data, et_coupling, dftb_potential, results, se_taper, se_store_int_env, se_nddo_mpole, se_nonbond_env, admm_env, lri_env, lri_density, exstate_env, ec_env, harris_env, dispersion_env, gcp_env, vee, rho_external, external_vxc, mask, mp2_env, bs_env, kg_env, wanniercentres, atprop, ls_scf_env, do_transport, transport_env, v_hartree_rspace, s_mstruct_changed, rho_changed, potential_changed, forces_up_to_date, mscfg_env, almo_scf_env, gradient_history, variable_history, embed_pot, spin_embed_pot, polar_env, mos_last_converged, eeq, rhs, do_rixs, tb_tblite)
Get the QUICKSTEP environment.
subroutine, public set_qs_env(qs_env, super_cell, mos, qmmm, qmmm_periodic, mimic, ewald_env, ewald_pw, mpools, rho_external, external_vxc, mask, scf_control, rel_control, qs_charges, ks_env, ks_qmmm_env, wf_history, scf_env, active_space, input, oce, rho_atom_set, rho0_atom_set, rho0_mpole, run_rtp, rtp, rhoz_set, rhoz_tot, ecoul_1c, has_unit_metric, requires_mo_derivs, mo_derivs, mo_loc_history, efield, rhoz_cneo_set, linres_control, xas_env, cp_ddapc_env, cp_ddapc_ewald, outer_scf_history, outer_scf_ihistory, x_data, et_coupling, dftb_potential, se_taper, se_store_int_env, se_nddo_mpole, se_nonbond_env, admm_env, ls_scf_env, do_transport, transport_env, lri_env, lri_density, exstate_env, ec_env, dispersion_env, harris_env, gcp_env, mp2_env, bs_env, kg_env, force, kpoints, wanniercentres, almo_scf_env, gradient_history, variable_history, embed_pot, spin_embed_pot, polar_env, mos_last_converged, eeq, rhs, do_rixs, tb_tblite)
Set the QUICKSTEP environment.
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, hund_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, proj_shell_charge, lr_atom, do_mtlr, u_j_loop, ao_coef, 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...
Finite-volume Kubo-Greenwood transport from converged Quickstep matrices.
subroutine, public qs_scf_post_kubo_transport(qs_env)
Compute and print the finite-volume Kubo-Greenwood conductivity tensor.
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:182
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, max_nmo, 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_kp(qs_env, dft_section, pdos_print_key, write_pdos, write_pdos_curve)
Compute and write broadened projected density of states for k-point calculations.
Definition qs_pdos.F:1073
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, unoccupied_orbs, unoccupied_evals, pdos_print_key, write_pdos, write_pdos_curve)
Compute and write projected density of states.
Definition qs_pdos.F:155
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 their eigenvalues for all spin channels.
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.
character(len=default_string_length) function cp_section_key_concat_to_absolute(self, extend_by)
Append extend_by to the absolute path of the base section.
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:746
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...
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...
contains arbitrary information which need to be stored
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 ...
Container for information about total charges on the grids.
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.