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