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