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