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