Line data Source code
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 : ! **************************************************************************************************
15 : MODULE qs_scf_post_gpw
16 : USE admm_types, ONLY: admm_type
17 : USE admm_utils, ONLY: admm_correct_for_eigenvalues,&
18 : admm_uncorrect_for_eigenvalues
19 : USE ai_onecenter, ONLY: sg_overlap
20 : USE atom_kind_orbitals, ONLY: calculate_atomic_density
21 : USE atomic_kind_types, ONLY: atomic_kind_type,&
22 : get_atomic_kind
23 : USE basis_set_types, ONLY: gto_basis_set_p_type,&
24 : gto_basis_set_type
25 : USE cell_types, ONLY: cell_type
26 : USE cp_array_utils, ONLY: cp_1d_r_p_type
27 : USE cp_blacs_env, ONLY: cp_blacs_env_type
28 : USE cp_control_types, ONLY: dft_control_type
29 : USE cp_dbcsr_api, ONLY: dbcsr_add,&
30 : dbcsr_p_type,&
31 : dbcsr_type
32 : USE cp_dbcsr_operations, ONLY: copy_dbcsr_to_fm,&
33 : dbcsr_deallocate_matrix_set
34 : USE cp_dbcsr_output, ONLY: cp_dbcsr_write_sparse_matrix
35 : USE cp_ddapc_util, ONLY: get_ddapc
36 : USE cp_fm_diag, ONLY: choose_eigv_solver
37 : USE cp_fm_struct, ONLY: cp_fm_struct_create,&
38 : cp_fm_struct_release,&
39 : cp_fm_struct_type
40 : USE cp_fm_types, ONLY: cp_fm_create,&
41 : cp_fm_get_info,&
42 : cp_fm_init_random,&
43 : cp_fm_release,&
44 : cp_fm_to_fm,&
45 : cp_fm_type
46 : USE cp_log_handling, ONLY: cp_get_default_logger,&
47 : cp_logger_get_default_io_unit,&
48 : cp_logger_type,&
49 : cp_to_string
50 : USE cp_output_handling, ONLY: cp_p_file,&
51 : cp_print_key_finished_output,&
52 : cp_print_key_should_output,&
53 : cp_print_key_unit_nr
54 : USE cp_realspace_grid_cube, ONLY: cp_pw_to_cube
55 : USE dct, ONLY: pw_shrink
56 : USE ed_analysis, ONLY: edmf_analysis
57 : USE eeq_method, ONLY: eeq_print
58 : USE et_coupling_types, ONLY: set_et_coupling_type
59 : USE hfx_ri, ONLY: print_ri_hfx
60 : USE hirshfeld_methods, ONLY: comp_hirshfeld_charges,&
61 : comp_hirshfeld_i_charges,&
62 : create_shape_function,&
63 : save_hirshfeld_charges,&
64 : write_hirshfeld_charges
65 : USE hirshfeld_types, ONLY: create_hirshfeld_type,&
66 : hirshfeld_type,&
67 : release_hirshfeld_type,&
68 : set_hirshfeld_info
69 : USE iao_analysis, ONLY: iao_wfn_analysis
70 : USE iao_types, ONLY: iao_env_type,&
71 : iao_read_input
72 : USE input_constants, ONLY: &
73 : do_loc_both, do_loc_homo, do_loc_jacobi, do_loc_lumo, do_loc_mixed, do_loc_none, &
74 : ot_precond_full_all, radius_covalent, radius_user, ref_charge_atomic, ref_charge_mulliken
75 : USE input_section_types, ONLY: section_get_ival,&
76 : section_get_ivals,&
77 : section_get_lval,&
78 : section_get_rval,&
79 : section_vals_get,&
80 : section_vals_get_subs_vals,&
81 : section_vals_type,&
82 : section_vals_val_get
83 : USE kinds, ONLY: default_path_length,&
84 : default_string_length,&
85 : dp
86 : USE kpoint_types, ONLY: kpoint_type
87 : USE mao_wfn_analysis, ONLY: mao_analysis
88 : USE mathconstants, ONLY: pi
89 : USE memory_utilities, ONLY: reallocate
90 : USE message_passing, ONLY: mp_para_env_type
91 : USE minbas_wfn_analysis, ONLY: minbas_analysis
92 : USE molden_utils, ONLY: write_mos_molden
93 : USE molecule_types, ONLY: molecule_type
94 : USE mulliken, ONLY: mulliken_charges
95 : USE orbital_pointers, ONLY: indso
96 : USE particle_list_types, ONLY: particle_list_type
97 : USE particle_types, ONLY: particle_type
98 : USE physcon, ONLY: angstrom,&
99 : evolt
100 : USE population_analyses, ONLY: lowdin_population_analysis,&
101 : mulliken_population_analysis
102 : USE preconditioner_types, ONLY: preconditioner_type
103 : USE ps_implicit_types, ONLY: MIXED_BC,&
104 : MIXED_PERIODIC_BC,&
105 : NEUMANN_BC,&
106 : PERIODIC_BC
107 : USE pw_env_types, ONLY: pw_env_get,&
108 : pw_env_type
109 : USE pw_grids, ONLY: get_pw_grid_info
110 : USE pw_methods, ONLY: pw_axpy,&
111 : pw_copy,&
112 : pw_derive,&
113 : pw_integrate_function,&
114 : pw_scale,&
115 : pw_transfer,&
116 : pw_zero
117 : USE pw_poisson_methods, ONLY: pw_poisson_solve
118 : USE pw_poisson_types, ONLY: pw_poisson_implicit,&
119 : pw_poisson_type
120 : USE pw_pool_types, ONLY: pw_pool_p_type,&
121 : pw_pool_type
122 : USE pw_types, ONLY: pw_c1d_gs_type,&
123 : pw_r3d_rs_type
124 : USE qs_chargemol, ONLY: write_wfx
125 : USE qs_collocate_density, ONLY: calculate_rho_resp_all,&
126 : calculate_wavefunction
127 : USE qs_commutators, ONLY: build_com_hr_matrix
128 : USE qs_core_energies, ONLY: calculate_ptrace
129 : USE qs_dos, ONLY: calculate_dos,&
130 : calculate_dos_kp
131 : USE qs_electric_field_gradient, ONLY: qs_efg_calc
132 : USE qs_elf_methods, ONLY: qs_elf_calc
133 : USE qs_energy_types, ONLY: qs_energy_type
134 : USE qs_energy_window, ONLY: energy_windows
135 : USE qs_environment_types, ONLY: get_qs_env,&
136 : qs_environment_type,&
137 : set_qs_env
138 : USE qs_epr_hyp, ONLY: qs_epr_hyp_calc
139 : USE qs_grid_atom, ONLY: grid_atom_type
140 : USE qs_integral_utils, ONLY: basis_set_list_setup
141 : USE qs_kind_types, ONLY: get_qs_kind,&
142 : qs_kind_type
143 : USE qs_ks_methods, ONLY: calc_rho_tot_gspace,&
144 : qs_ks_update_qs_env
145 : USE qs_ks_types, ONLY: qs_ks_did_change
146 : USE qs_loc_dipole, ONLY: loc_dipole
147 : USE qs_loc_states, ONLY: get_localization_info
148 : USE qs_loc_types, ONLY: qs_loc_env_create,&
149 : qs_loc_env_release,&
150 : qs_loc_env_type
151 : USE qs_loc_utils, ONLY: loc_write_restart,&
152 : qs_loc_control_init,&
153 : qs_loc_env_init,&
154 : qs_loc_init,&
155 : retain_history
156 : USE qs_local_properties, ONLY: qs_local_energy,&
157 : qs_local_stress
158 : USE qs_mo_io, ONLY: write_dm_binary_restart
159 : USE qs_mo_methods, ONLY: calculate_subspace_eigenvalues,&
160 : make_mo_eig
161 : USE qs_mo_occupation, ONLY: set_mo_occupation
162 : USE qs_mo_types, ONLY: get_mo_set,&
163 : mo_set_type
164 : USE qs_moments, ONLY: qs_moment_berry_phase,&
165 : qs_moment_kpoints,&
166 : qs_moment_locop
167 : USE qs_neighbor_list_types, ONLY: get_iterator_info,&
168 : get_neighbor_list_set_p,&
169 : neighbor_list_iterate,&
170 : neighbor_list_iterator_create,&
171 : neighbor_list_iterator_p_type,&
172 : neighbor_list_iterator_release,&
173 : neighbor_list_set_p_type
174 : USE qs_ot_eigensolver, ONLY: ot_eigensolver
175 : USE qs_pdos, ONLY: calculate_projected_dos
176 : USE qs_resp, ONLY: resp_fit
177 : USE qs_rho0_types, ONLY: get_rho0_mpole,&
178 : mpole_rho_atom,&
179 : rho0_mpole_type
180 : USE qs_rho_atom_types, ONLY: rho_atom_type
181 : USE qs_rho_methods, ONLY: qs_rho_update_rho
182 : USE qs_rho_types, ONLY: qs_rho_get,&
183 : qs_rho_type
184 : USE qs_scf_csr_write, ONLY: write_hcore_matrix_csr,&
185 : write_ks_matrix_csr,&
186 : write_p_matrix_csr,&
187 : write_s_matrix_csr
188 : USE qs_scf_output, ONLY: qs_scf_write_mos
189 : USE qs_scf_types, ONLY: ot_method_nr,&
190 : qs_scf_env_type
191 : USE qs_scf_wfn_mix, ONLY: wfn_mix
192 : USE qs_subsys_types, ONLY: qs_subsys_get,&
193 : qs_subsys_type
194 : USE qs_wannier90, ONLY: wannier90_interface
195 : USE s_square_methods, ONLY: compute_s_square
196 : USE scf_control_types, ONLY: scf_control_type
197 : USE stm_images, ONLY: th_stm_image
198 : USE transport, ONLY: qs_scf_post_transport
199 : USE trexio_utils, ONLY: write_trexio
200 : USE virial_types, ONLY: virial_type
201 : USE voronoi_interface, ONLY: entry_voronoi_or_bqb
202 : USE xray_diffraction, ONLY: calculate_rhotot_elec_gspace,&
203 : xray_diffraction_spectrum
204 : #include "./base/base_uses.f90"
205 :
206 : IMPLICIT NONE
207 : PRIVATE
208 :
209 : ! Global parameters
210 : CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_scf_post_gpw'
211 : PUBLIC :: scf_post_calculation_gpw, &
212 : qs_scf_post_moments, &
213 : write_mo_dependent_results, &
214 : write_mo_free_results
215 :
216 : PUBLIC :: make_lumo_gpw
217 :
218 : CONTAINS
219 :
220 : ! **************************************************************************************************
221 : !> \brief collects possible post - scf calculations and prints info / computes properties.
222 : !> \param qs_env the qs_env in which the qs_env lives
223 : !> \param wf_type ...
224 : !> \param do_mp2 ...
225 : !> \par History
226 : !> 02.2003 created [fawzi]
227 : !> 10.2004 moved here from qs_scf [Joost VandeVondele]
228 : !> started splitting out different subroutines
229 : !> 10.2015 added header for wave-function correlated methods [Vladimir Rybkin]
230 : !> \author fawzi
231 : !> \note
232 : !> this function changes mo_eigenvectors and mo_eigenvalues, depending on the print keys.
233 : !> In particular, MO_CUBES causes the MOs to be rotated to make them eigenstates of the KS
234 : !> matrix, and mo_eigenvalues is updated accordingly. This can, for unconverged wavefunctions,
235 : !> change afterwards slightly the forces (hence small numerical differences between MD
236 : !> with and without the debug print level). Ideally this should not happen...
237 : ! **************************************************************************************************
238 10059 : SUBROUTINE scf_post_calculation_gpw(qs_env, wf_type, do_mp2)
239 :
240 : TYPE(qs_environment_type), POINTER :: qs_env
241 : CHARACTER(6), OPTIONAL :: wf_type
242 : LOGICAL, OPTIONAL :: do_mp2
243 :
244 : CHARACTER(len=*), PARAMETER :: routineN = 'scf_post_calculation_gpw'
245 :
246 : INTEGER :: handle, homo, ispin, min_lumos, n_rep, &
247 : nchk_nmoloc, nhomo, nlumo, nlumo_stm, &
248 : nlumos, nmo, nspins, output_unit, &
249 : unit_nr
250 10059 : INTEGER, DIMENSION(:, :, :), POINTER :: marked_states
251 : LOGICAL :: check_write, compute_lumos, do_homo, do_kpoints, do_mixed, do_mo_cubes, do_stm, &
252 : do_wannier_cubes, has_homo, has_lumo, loc_explicit, loc_print_explicit, my_do_mp2, &
253 : my_localized_wfn, p_loc, p_loc_homo, p_loc_lumo, p_loc_mixed
254 : REAL(dp) :: e_kin
255 : REAL(KIND=dp) :: gap, homo_lumo(2, 2), total_zeff_corr
256 10059 : REAL(KIND=dp), DIMENSION(:), POINTER :: mo_eigenvalues
257 : TYPE(admm_type), POINTER :: admm_env
258 10059 : TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
259 10059 : TYPE(cp_1d_r_p_type), DIMENSION(:), POINTER :: mixed_evals, occupied_evals, &
260 10059 : unoccupied_evals, unoccupied_evals_stm
261 10059 : TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:) :: mixed_orbs, occupied_orbs
262 : TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:), &
263 10059 : TARGET :: homo_localized, lumo_localized, &
264 10059 : mixed_localized
265 10059 : TYPE(cp_fm_type), DIMENSION(:), POINTER :: lumo_ptr, mo_loc_history, &
266 10059 : unoccupied_orbs, unoccupied_orbs_stm
267 : TYPE(cp_fm_type), POINTER :: mo_coeff
268 : TYPE(cp_logger_type), POINTER :: logger
269 10059 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: ks_rmpv, matrix_p_mp2, matrix_s, &
270 10059 : mo_derivs
271 10059 : TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: kinetic_m, rho_ao
272 : TYPE(dft_control_type), POINTER :: dft_control
273 10059 : TYPE(mo_set_type), DIMENSION(:), POINTER :: mos
274 10059 : TYPE(molecule_type), POINTER :: molecule_set(:)
275 : TYPE(mp_para_env_type), POINTER :: para_env
276 : TYPE(particle_list_type), POINTER :: particles
277 10059 : TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
278 : TYPE(pw_c1d_gs_type) :: wf_g
279 : TYPE(pw_env_type), POINTER :: pw_env
280 10059 : TYPE(pw_pool_p_type), DIMENSION(:), POINTER :: pw_pools
281 : TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
282 : TYPE(pw_r3d_rs_type) :: wf_r
283 10059 : TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
284 : TYPE(qs_loc_env_type), POINTER :: qs_loc_env_homo, qs_loc_env_lumo, &
285 : qs_loc_env_mixed
286 : TYPE(qs_rho_type), POINTER :: rho
287 : TYPE(qs_scf_env_type), POINTER :: scf_env
288 : TYPE(qs_subsys_type), POINTER :: subsys
289 : TYPE(scf_control_type), POINTER :: scf_control
290 : TYPE(section_vals_type), POINTER :: dft_section, input, loc_print_section, &
291 : localize_section, print_key, &
292 : stm_section
293 :
294 10059 : CALL timeset(routineN, handle)
295 :
296 10059 : logger => cp_get_default_logger()
297 10059 : output_unit = cp_logger_get_default_io_unit(logger)
298 :
299 : ! Print out the type of wavefunction to distinguish between SCF and post-SCF
300 10059 : my_do_mp2 = .FALSE.
301 10059 : IF (PRESENT(do_mp2)) my_do_mp2 = do_mp2
302 10059 : IF (PRESENT(wf_type)) THEN
303 322 : IF (output_unit > 0) THEN
304 161 : WRITE (UNIT=output_unit, FMT='(/,(T1,A))') REPEAT("-", 40)
305 161 : WRITE (UNIT=output_unit, FMT='(/,(T3,A,T19,A,T25,A))') "Properties from ", wf_type, " density"
306 161 : WRITE (UNIT=output_unit, FMT='(/,(T1,A))') REPEAT("-", 40)
307 : END IF
308 : END IF
309 :
310 : ! Writes the data that is already available in qs_env
311 10059 : CALL get_qs_env(qs_env, scf_env=scf_env)
312 :
313 10059 : my_localized_wfn = .FALSE.
314 10059 : NULLIFY (admm_env, dft_control, pw_env, auxbas_pw_pool, pw_pools, mos, rho, &
315 10059 : mo_coeff, ks_rmpv, matrix_s, qs_loc_env_homo, qs_loc_env_lumo, scf_control, &
316 10059 : unoccupied_orbs, mo_eigenvalues, unoccupied_evals, &
317 10059 : unoccupied_evals_stm, molecule_set, mo_derivs, &
318 10059 : subsys, particles, input, print_key, kinetic_m, marked_states, &
319 10059 : mixed_evals, qs_loc_env_mixed)
320 10059 : NULLIFY (lumo_ptr, rho_ao)
321 :
322 10059 : has_homo = .FALSE.
323 10059 : has_lumo = .FALSE.
324 10059 : p_loc = .FALSE.
325 10059 : p_loc_homo = .FALSE.
326 10059 : p_loc_lumo = .FALSE.
327 10059 : p_loc_mixed = .FALSE.
328 :
329 10059 : CPASSERT(ASSOCIATED(scf_env))
330 10059 : CPASSERT(ASSOCIATED(qs_env))
331 : ! Here we start with data that needs a postprocessing...
332 : CALL get_qs_env(qs_env, &
333 : dft_control=dft_control, &
334 : molecule_set=molecule_set, &
335 : scf_control=scf_control, &
336 : do_kpoints=do_kpoints, &
337 : input=input, &
338 : subsys=subsys, &
339 : rho=rho, &
340 : pw_env=pw_env, &
341 : particle_set=particle_set, &
342 : atomic_kind_set=atomic_kind_set, &
343 10059 : qs_kind_set=qs_kind_set)
344 10059 : CALL qs_subsys_get(subsys, particles=particles)
345 :
346 10059 : CALL qs_rho_get(rho, rho_ao_kp=rho_ao)
347 :
348 10059 : IF (my_do_mp2) THEN
349 : ! Get the HF+MP2 density
350 322 : CALL get_qs_env(qs_env, matrix_p_mp2=matrix_p_mp2)
351 742 : DO ispin = 1, dft_control%nspins
352 742 : CALL dbcsr_add(rho_ao(ispin, 1)%matrix, matrix_p_mp2(ispin)%matrix, 1.0_dp, 1.0_dp)
353 : END DO
354 322 : CALL qs_rho_update_rho(rho, qs_env=qs_env)
355 322 : CALL qs_ks_did_change(qs_env%ks_env, rho_changed=.TRUE.)
356 : ! In MP2 case update the Hartree potential
357 322 : CALL update_hartree_with_mp2(rho, qs_env)
358 : END IF
359 :
360 10059 : CALL write_available_results(qs_env, scf_env)
361 :
362 : ! **** the kinetic energy
363 10059 : IF (cp_print_key_should_output(logger%iter_info, input, &
364 : "DFT%PRINT%KINETIC_ENERGY") /= 0) THEN
365 80 : CALL get_qs_env(qs_env, kinetic_kp=kinetic_m)
366 80 : CPASSERT(ASSOCIATED(kinetic_m))
367 80 : CPASSERT(ASSOCIATED(kinetic_m(1, 1)%matrix))
368 80 : CALL calculate_ptrace(kinetic_m, rho_ao, e_kin, dft_control%nspins)
369 : unit_nr = cp_print_key_unit_nr(logger, input, "DFT%PRINT%KINETIC_ENERGY", &
370 80 : extension=".Log")
371 80 : IF (unit_nr > 0) THEN
372 40 : WRITE (unit_nr, '(T3,A,T55,F25.14)') "Electronic kinetic energy:", e_kin
373 : END IF
374 : CALL cp_print_key_finished_output(unit_nr, logger, input, &
375 80 : "DFT%PRINT%KINETIC_ENERGY")
376 : END IF
377 :
378 : ! Atomic Charges that require further computation
379 10059 : CALL qs_scf_post_charges(input, logger, qs_env)
380 :
381 : ! Moments of charge distribution
382 10059 : CALL qs_scf_post_moments(input, logger, qs_env, output_unit)
383 :
384 : ! Determine if we need to computer properties using the localized centers
385 10059 : dft_section => section_vals_get_subs_vals(input, "DFT")
386 10059 : localize_section => section_vals_get_subs_vals(dft_section, "LOCALIZE")
387 10059 : loc_print_section => section_vals_get_subs_vals(localize_section, "PRINT")
388 10059 : CALL section_vals_get(localize_section, explicit=loc_explicit)
389 10059 : CALL section_vals_get(loc_print_section, explicit=loc_print_explicit)
390 :
391 : ! Print_keys controlled by localization
392 10059 : IF (loc_print_explicit) THEN
393 96 : print_key => section_vals_get_subs_vals(loc_print_section, "MOLECULAR_DIPOLES")
394 96 : p_loc = BTEST(cp_print_key_should_output(logger%iter_info, print_key), cp_p_file)
395 96 : print_key => section_vals_get_subs_vals(loc_print_section, "TOTAL_DIPOLE")
396 96 : p_loc = p_loc .OR. BTEST(cp_print_key_should_output(logger%iter_info, print_key), cp_p_file)
397 96 : print_key => section_vals_get_subs_vals(loc_print_section, "WANNIER_CENTERS")
398 96 : p_loc = p_loc .OR. BTEST(cp_print_key_should_output(logger%iter_info, print_key), cp_p_file)
399 96 : print_key => section_vals_get_subs_vals(loc_print_section, "WANNIER_SPREADS")
400 96 : p_loc = p_loc .OR. BTEST(cp_print_key_should_output(logger%iter_info, print_key), cp_p_file)
401 96 : print_key => section_vals_get_subs_vals(loc_print_section, "WANNIER_CUBES")
402 96 : p_loc = p_loc .OR. BTEST(cp_print_key_should_output(logger%iter_info, print_key), cp_p_file)
403 96 : print_key => section_vals_get_subs_vals(loc_print_section, "MOLECULAR_STATES")
404 96 : p_loc = p_loc .OR. BTEST(cp_print_key_should_output(logger%iter_info, print_key), cp_p_file)
405 96 : print_key => section_vals_get_subs_vals(loc_print_section, "MOLECULAR_MOMENTS")
406 96 : p_loc = p_loc .OR. BTEST(cp_print_key_should_output(logger%iter_info, print_key), cp_p_file)
407 96 : print_key => section_vals_get_subs_vals(loc_print_section, "WANNIER_STATES")
408 96 : p_loc = p_loc .OR. BTEST(cp_print_key_should_output(logger%iter_info, print_key), cp_p_file)
409 : ELSE
410 : p_loc = .FALSE.
411 : END IF
412 10059 : IF (loc_explicit) THEN
413 : p_loc_homo = (section_get_ival(localize_section, "STATES") == do_loc_homo .OR. &
414 96 : section_get_ival(localize_section, "STATES") == do_loc_both) .AND. p_loc
415 : p_loc_lumo = (section_get_ival(localize_section, "STATES") == do_loc_lumo .OR. &
416 96 : section_get_ival(localize_section, "STATES") == do_loc_both) .AND. p_loc
417 96 : p_loc_mixed = (section_get_ival(localize_section, "STATES") == do_loc_mixed) .AND. p_loc
418 96 : CALL section_vals_val_get(localize_section, "LIST_UNOCCUPIED", n_rep_val=n_rep)
419 : ELSE
420 9963 : p_loc_homo = .FALSE.
421 9963 : p_loc_lumo = .FALSE.
422 9963 : p_loc_mixed = .FALSE.
423 9963 : n_rep = 0
424 : END IF
425 :
426 10059 : IF (n_rep == 0 .AND. p_loc_lumo) THEN
427 : CALL cp_abort(__LOCATION__, "No LIST_UNOCCUPIED was specified, "// &
428 0 : "therefore localization of unoccupied states will be skipped!")
429 0 : p_loc_lumo = .FALSE.
430 : END IF
431 :
432 : ! Control for STM
433 10059 : stm_section => section_vals_get_subs_vals(input, "DFT%PRINT%STM")
434 10059 : CALL section_vals_get(stm_section, explicit=do_stm)
435 10059 : nlumo_stm = 0
436 10059 : IF (do_stm) nlumo_stm = section_get_ival(stm_section, "NLUMO")
437 :
438 : ! check for CUBES (MOs and WANNIERS)
439 : do_mo_cubes = BTEST(cp_print_key_should_output(logger%iter_info, dft_section, "PRINT%MO_CUBES") &
440 10059 : , cp_p_file)
441 10059 : IF (loc_print_explicit) THEN
442 : do_wannier_cubes = BTEST(cp_print_key_should_output(logger%iter_info, loc_print_section, &
443 96 : "WANNIER_CUBES"), cp_p_file)
444 : ELSE
445 : do_wannier_cubes = .FALSE.
446 : END IF
447 10059 : nlumo = section_get_ival(dft_section, "PRINT%MO_CUBES%NLUMO")
448 10059 : nhomo = section_get_ival(dft_section, "PRINT%MO_CUBES%NHOMO")
449 :
450 : ! Setup the grids needed to compute a wavefunction given a vector..
451 10059 : IF (((do_mo_cubes .OR. do_wannier_cubes) .AND. (nlumo /= 0 .OR. nhomo /= 0)) .OR. p_loc) THEN
452 : CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool, &
453 210 : pw_pools=pw_pools)
454 210 : CALL auxbas_pw_pool%create_pw(wf_r)
455 210 : CALL auxbas_pw_pool%create_pw(wf_g)
456 : END IF
457 :
458 10059 : IF (dft_control%restricted) THEN
459 : !For ROKS usefull only first term
460 74 : nspins = 1
461 : ELSE
462 9985 : nspins = dft_control%nspins
463 : END IF
464 : !Some info about ROKS
465 10059 : IF (dft_control%restricted .AND. (do_mo_cubes .OR. p_loc_homo)) THEN
466 0 : CALL cp_abort(__LOCATION__, "Unclear how we define MOs / localization in the restricted case ... ")
467 : ! It is possible to obtain Wannier centers for ROKS without rotations for SINGLE OCCUPIED ORBITALS
468 : END IF
469 : ! Makes the MOs eigenstates, computes eigenvalues, write cubes
470 10059 : IF (do_kpoints) THEN
471 226 : CPWARN_IF(do_mo_cubes, "Print MO cubes not implemented for k-point calculations")
472 : ELSE
473 : CALL get_qs_env(qs_env, &
474 : mos=mos, &
475 9833 : matrix_ks=ks_rmpv)
476 9833 : IF ((do_mo_cubes .AND. nhomo /= 0) .OR. do_stm) THEN
477 134 : CALL get_qs_env(qs_env, mo_derivs=mo_derivs)
478 134 : IF (dft_control%do_admm) THEN
479 0 : CALL get_qs_env(qs_env, admm_env=admm_env)
480 0 : CALL make_mo_eig(mos, nspins, ks_rmpv, scf_control, mo_derivs, admm_env=admm_env)
481 : ELSE
482 134 : IF (dft_control%hairy_probes) THEN
483 0 : scf_control%smear%do_smear = .FALSE.
484 : CALL make_mo_eig(mos, dft_control%nspins, ks_rmpv, scf_control, mo_derivs, &
485 : hairy_probes=dft_control%hairy_probes, &
486 0 : probe=dft_control%probe)
487 : ELSE
488 134 : CALL make_mo_eig(mos, dft_control%nspins, ks_rmpv, scf_control, mo_derivs)
489 : END IF
490 : END IF
491 288 : DO ispin = 1, dft_control%nspins
492 154 : CALL get_mo_set(mo_set=mos(ispin), eigenvalues=mo_eigenvalues, homo=homo)
493 288 : homo_lumo(ispin, 1) = mo_eigenvalues(homo)
494 : END DO
495 : has_homo = .TRUE.
496 : END IF
497 9833 : IF (do_mo_cubes .AND. nhomo /= 0) THEN
498 274 : DO ispin = 1, nspins
499 : ! Prints the cube files of OCCUPIED ORBITALS
500 : CALL get_mo_set(mo_set=mos(ispin), mo_coeff=mo_coeff, &
501 146 : eigenvalues=mo_eigenvalues, homo=homo, nmo=nmo)
502 : CALL qs_scf_post_occ_cubes(input, dft_section, dft_control, logger, qs_env, &
503 274 : mo_coeff, wf_g, wf_r, particles, homo, ispin)
504 : END DO
505 : END IF
506 : END IF
507 :
508 : ! Initialize the localization environment, needed e.g. for wannier functions and molecular states
509 : ! Gets localization info for the occupied orbs
510 : ! - Possibly gets wannier functions
511 : ! - Possibly gets molecular states
512 10059 : IF (p_loc_homo) THEN
513 90 : IF (do_kpoints) THEN
514 0 : CPWARN("Localization not implemented for k-point calculations!")
515 : ELSEIF (dft_control%restricted &
516 : .AND. (section_get_ival(localize_section, "METHOD") /= do_loc_none) &
517 90 : .AND. (section_get_ival(localize_section, "METHOD") /= do_loc_jacobi)) THEN
518 0 : CPABORT("ROKS works only with LOCALIZE METHOD NONE or JACOBI")
519 : ELSE
520 376 : ALLOCATE (occupied_orbs(dft_control%nspins))
521 376 : ALLOCATE (occupied_evals(dft_control%nspins))
522 376 : ALLOCATE (homo_localized(dft_control%nspins))
523 196 : DO ispin = 1, dft_control%nspins
524 : CALL get_mo_set(mo_set=mos(ispin), mo_coeff=mo_coeff, &
525 106 : eigenvalues=mo_eigenvalues)
526 106 : occupied_orbs(ispin) = mo_coeff
527 106 : occupied_evals(ispin)%array => mo_eigenvalues
528 106 : CALL cp_fm_create(homo_localized(ispin), occupied_orbs(ispin)%matrix_struct)
529 196 : CALL cp_fm_to_fm(occupied_orbs(ispin), homo_localized(ispin))
530 : END DO
531 :
532 90 : CALL get_qs_env(qs_env, mo_loc_history=mo_loc_history)
533 90 : do_homo = .TRUE.
534 :
535 720 : ALLOCATE (qs_loc_env_homo)
536 90 : CALL qs_loc_env_create(qs_loc_env_homo)
537 90 : CALL qs_loc_control_init(qs_loc_env_homo, localize_section, do_homo=do_homo)
538 : CALL qs_loc_init(qs_env, qs_loc_env_homo, localize_section, homo_localized, do_homo, &
539 90 : do_mo_cubes, mo_loc_history=mo_loc_history)
540 : CALL get_localization_info(qs_env, qs_loc_env_homo, localize_section, homo_localized, &
541 90 : wf_r, wf_g, particles, occupied_orbs, occupied_evals, marked_states)
542 :
543 : !retain the homo_localized for future use
544 90 : IF (qs_loc_env_homo%localized_wfn_control%use_history) THEN
545 10 : CALL retain_history(mo_loc_history, homo_localized)
546 10 : CALL set_qs_env(qs_env, mo_loc_history=mo_loc_history)
547 : END IF
548 :
549 : !write restart for localization of occupied orbitals
550 : CALL loc_write_restart(qs_loc_env_homo, loc_print_section, mos, &
551 90 : homo_localized, do_homo)
552 90 : CALL cp_fm_release(homo_localized)
553 90 : DEALLOCATE (occupied_orbs)
554 90 : DEALLOCATE (occupied_evals)
555 : ! Print Total Dipole if the localization has been performed
556 180 : IF (qs_loc_env_homo%do_localize) THEN
557 74 : CALL loc_dipole(input, dft_control, qs_loc_env_homo, logger, qs_env)
558 : END IF
559 : END IF
560 : END IF
561 :
562 : ! Gets the lumos, and eigenvalues for the lumos, and localize them if requested
563 10059 : IF (do_kpoints) THEN
564 226 : IF (do_mo_cubes .OR. p_loc_lumo) THEN
565 : ! nothing at the moment, not implemented
566 2 : CPWARN("Localization and MO related output not implemented for k-point calculations!")
567 : END IF
568 : ELSE
569 9833 : compute_lumos = do_mo_cubes .AND. nlumo /= 0
570 9833 : compute_lumos = compute_lumos .OR. p_loc_lumo
571 :
572 21556 : DO ispin = 1, dft_control%nspins
573 11723 : CALL get_mo_set(mo_set=mos(ispin), homo=homo, nmo=nmo)
574 33231 : compute_lumos = compute_lumos .AND. homo == nmo
575 : END DO
576 :
577 9833 : IF (do_mo_cubes .AND. .NOT. compute_lumos) THEN
578 :
579 96 : nlumo = section_get_ival(dft_section, "PRINT%MO_CUBES%NLUMO")
580 194 : DO ispin = 1, dft_control%nspins
581 :
582 98 : CALL get_mo_set(mo_set=mos(ispin), homo=homo, nmo=nmo, eigenvalues=mo_eigenvalues)
583 194 : IF (nlumo > nmo - homo) THEN
584 : ! this case not yet implemented
585 : ELSE
586 98 : IF (nlumo == -1) THEN
587 0 : nlumo = nmo - homo
588 : END IF
589 98 : IF (output_unit > 0) WRITE (output_unit, *) " "
590 98 : IF (output_unit > 0) WRITE (output_unit, *) " Lowest eigenvalues of the unoccupied subspace spin ", ispin
591 98 : IF (output_unit > 0) WRITE (output_unit, *) "---------------------------------------------"
592 98 : IF (output_unit > 0) WRITE (output_unit, '(4(1X,1F16.8))') mo_eigenvalues(homo + 1:homo + nlumo)
593 :
594 : ! Prints the cube files of UNOCCUPIED ORBITALS
595 98 : CALL get_mo_set(mo_set=mos(ispin), mo_coeff=mo_coeff)
596 : CALL qs_scf_post_unocc_cubes(input, dft_section, dft_control, logger, qs_env, &
597 98 : mo_coeff, wf_g, wf_r, particles, nlumo, homo, ispin, lumo=homo + 1)
598 : END IF
599 : END DO
600 :
601 : END IF
602 :
603 9801 : IF (compute_lumos) THEN
604 32 : check_write = .TRUE.
605 32 : min_lumos = nlumo
606 32 : IF (nlumo == 0) check_write = .FALSE.
607 32 : IF (p_loc_lumo) THEN
608 6 : do_homo = .FALSE.
609 48 : ALLOCATE (qs_loc_env_lumo)
610 6 : CALL qs_loc_env_create(qs_loc_env_lumo)
611 6 : CALL qs_loc_control_init(qs_loc_env_lumo, localize_section, do_homo=do_homo)
612 98 : min_lumos = MAX(MAXVAL(qs_loc_env_lumo%localized_wfn_control%loc_states(:, :)), nlumo)
613 : END IF
614 :
615 144 : ALLOCATE (unoccupied_orbs(dft_control%nspins))
616 144 : ALLOCATE (unoccupied_evals(dft_control%nspins))
617 32 : CALL make_lumo_gpw(qs_env, scf_env, unoccupied_orbs, unoccupied_evals, min_lumos, nlumos)
618 32 : lumo_ptr => unoccupied_orbs
619 80 : DO ispin = 1, dft_control%nspins
620 48 : has_lumo = .TRUE.
621 48 : homo_lumo(ispin, 2) = unoccupied_evals(ispin)%array(1)
622 48 : CALL get_mo_set(mo_set=mos(ispin), homo=homo)
623 80 : IF (check_write) THEN
624 48 : IF (p_loc_lumo .AND. nlumo /= -1) nlumos = MIN(nlumo, nlumos)
625 : ! Prints the cube files of UNOCCUPIED ORBITALS
626 : CALL qs_scf_post_unocc_cubes(input, dft_section, dft_control, logger, qs_env, &
627 48 : unoccupied_orbs(ispin), wf_g, wf_r, particles, nlumos, homo, ispin)
628 : END IF
629 : END DO
630 :
631 64 : IF (p_loc_lumo) THEN
632 30 : ALLOCATE (lumo_localized(dft_control%nspins))
633 18 : DO ispin = 1, dft_control%nspins
634 12 : CALL cp_fm_create(lumo_localized(ispin), unoccupied_orbs(ispin)%matrix_struct)
635 18 : CALL cp_fm_to_fm(unoccupied_orbs(ispin), lumo_localized(ispin))
636 : END DO
637 : CALL qs_loc_init(qs_env, qs_loc_env_lumo, localize_section, lumo_localized, do_homo, do_mo_cubes, &
638 6 : evals=unoccupied_evals)
639 : CALL qs_loc_env_init(qs_loc_env_lumo, qs_loc_env_lumo%localized_wfn_control, qs_env, &
640 6 : loc_coeff=unoccupied_orbs)
641 : CALL get_localization_info(qs_env, qs_loc_env_lumo, localize_section, &
642 : lumo_localized, wf_r, wf_g, particles, &
643 6 : unoccupied_orbs, unoccupied_evals, marked_states)
644 : CALL loc_write_restart(qs_loc_env_lumo, loc_print_section, mos, homo_localized, do_homo, &
645 6 : evals=unoccupied_evals)
646 6 : lumo_ptr => lumo_localized
647 : END IF
648 : END IF
649 :
650 9833 : IF (has_homo .AND. has_lumo) THEN
651 32 : IF (output_unit > 0) WRITE (output_unit, *) " "
652 80 : DO ispin = 1, dft_control%nspins
653 80 : IF (.NOT. scf_control%smear%do_smear) THEN
654 48 : gap = homo_lumo(ispin, 2) - homo_lumo(ispin, 1)
655 48 : IF (output_unit > 0) WRITE (output_unit, '(T2,A,F12.6)') &
656 24 : "HOMO - LUMO gap [eV] :", gap*evolt
657 : END IF
658 : END DO
659 : END IF
660 : END IF
661 :
662 10059 : IF (p_loc_mixed) THEN
663 2 : IF (do_kpoints) THEN
664 0 : CPWARN("Localization not implemented for k-point calculations!")
665 2 : ELSEIF (dft_control%restricted) THEN
666 0 : IF (output_unit > 0) WRITE (output_unit, *) &
667 0 : " Unclear how we define MOs / localization in the restricted case... skipping"
668 : ELSE
669 :
670 8 : ALLOCATE (mixed_orbs(dft_control%nspins))
671 8 : ALLOCATE (mixed_evals(dft_control%nspins))
672 8 : ALLOCATE (mixed_localized(dft_control%nspins))
673 4 : DO ispin = 1, dft_control%nspins
674 : CALL get_mo_set(mo_set=mos(ispin), mo_coeff=mo_coeff, &
675 2 : eigenvalues=mo_eigenvalues)
676 2 : mixed_orbs(ispin) = mo_coeff
677 2 : mixed_evals(ispin)%array => mo_eigenvalues
678 2 : CALL cp_fm_create(mixed_localized(ispin), mixed_orbs(ispin)%matrix_struct)
679 4 : CALL cp_fm_to_fm(mixed_orbs(ispin), mixed_localized(ispin))
680 : END DO
681 :
682 2 : CALL get_qs_env(qs_env, mo_loc_history=mo_loc_history)
683 2 : do_homo = .FALSE.
684 2 : do_mixed = .TRUE.
685 2 : total_zeff_corr = scf_env%sum_zeff_corr
686 16 : ALLOCATE (qs_loc_env_mixed)
687 2 : CALL qs_loc_env_create(qs_loc_env_mixed)
688 2 : CALL qs_loc_control_init(qs_loc_env_mixed, localize_section, do_homo=do_homo, do_mixed=do_mixed)
689 : CALL qs_loc_init(qs_env, qs_loc_env_mixed, localize_section, mixed_localized, do_homo, &
690 : do_mo_cubes, mo_loc_history=mo_loc_history, tot_zeff_corr=total_zeff_corr, &
691 2 : do_mixed=do_mixed)
692 :
693 4 : DO ispin = 1, dft_control%nspins
694 4 : CALL cp_fm_get_info(mixed_localized(ispin), ncol_global=nchk_nmoloc)
695 : END DO
696 :
697 : CALL get_localization_info(qs_env, qs_loc_env_mixed, localize_section, mixed_localized, &
698 2 : wf_r, wf_g, particles, mixed_orbs, mixed_evals, marked_states)
699 :
700 : !retain the homo_localized for future use
701 2 : IF (qs_loc_env_mixed%localized_wfn_control%use_history) THEN
702 0 : CALL retain_history(mo_loc_history, mixed_localized)
703 0 : CALL set_qs_env(qs_env, mo_loc_history=mo_loc_history)
704 : END IF
705 :
706 : !write restart for localization of occupied orbitals
707 : CALL loc_write_restart(qs_loc_env_mixed, loc_print_section, mos, &
708 2 : mixed_localized, do_homo, do_mixed=do_mixed)
709 2 : CALL cp_fm_release(mixed_localized)
710 2 : DEALLOCATE (mixed_orbs)
711 4 : DEALLOCATE (mixed_evals)
712 : ! Print Total Dipole if the localization has been performed
713 : ! Revisit the formalism later
714 : !IF (qs_loc_env_mixed%do_localize) THEN
715 : ! CALL loc_dipole(input, dft_control, qs_loc_env_mixed, logger, qs_env)
716 : !END IF
717 : END IF
718 : END IF
719 :
720 : ! Deallocate grids needed to compute wavefunctions
721 10059 : IF (((do_mo_cubes .OR. do_wannier_cubes) .AND. (nlumo /= 0 .OR. nhomo /= 0)) .OR. p_loc) THEN
722 210 : CALL auxbas_pw_pool%give_back_pw(wf_r)
723 210 : CALL auxbas_pw_pool%give_back_pw(wf_g)
724 : END IF
725 :
726 : ! Destroy the localization environment
727 10059 : IF (.NOT. do_kpoints) THEN
728 9833 : IF (p_loc_homo) THEN
729 90 : CALL qs_loc_env_release(qs_loc_env_homo)
730 90 : DEALLOCATE (qs_loc_env_homo)
731 : END IF
732 9833 : IF (p_loc_lumo) THEN
733 6 : CALL qs_loc_env_release(qs_loc_env_lumo)
734 6 : DEALLOCATE (qs_loc_env_lumo)
735 : END IF
736 9833 : IF (p_loc_mixed) THEN
737 2 : CALL qs_loc_env_release(qs_loc_env_mixed)
738 2 : DEALLOCATE (qs_loc_env_mixed)
739 : END IF
740 : END IF
741 :
742 : ! generate a mix of wfns, and write to a restart
743 10059 : IF (do_kpoints) THEN
744 : ! nothing at the moment, not implemented
745 : ELSE
746 9833 : CALL get_qs_env(qs_env, matrix_s=matrix_s, para_env=para_env)
747 : CALL wfn_mix(mos, particle_set, dft_section, qs_kind_set, para_env, &
748 : output_unit, unoccupied_orbs=lumo_ptr, scf_env=scf_env, &
749 9833 : matrix_s=matrix_s, marked_states=marked_states)
750 :
751 9833 : IF (p_loc_lumo) CALL cp_fm_release(lumo_localized)
752 : END IF
753 10059 : IF (ASSOCIATED(marked_states)) THEN
754 16 : DEALLOCATE (marked_states)
755 : END IF
756 :
757 : ! This is just a deallocation for printing MO_CUBES or TDDFPT
758 10059 : IF (.NOT. do_kpoints) THEN
759 9833 : IF (compute_lumos) THEN
760 80 : DO ispin = 1, dft_control%nspins
761 48 : DEALLOCATE (unoccupied_evals(ispin)%array)
762 80 : CALL cp_fm_release(unoccupied_orbs(ispin))
763 : END DO
764 32 : DEALLOCATE (unoccupied_evals)
765 32 : DEALLOCATE (unoccupied_orbs)
766 : END IF
767 : END IF
768 :
769 : !stm images
770 10059 : IF (do_stm) THEN
771 6 : IF (do_kpoints) THEN
772 0 : CPWARN("STM not implemented for k-point calculations!")
773 : ELSE
774 6 : NULLIFY (unoccupied_orbs_stm, unoccupied_evals_stm)
775 6 : IF (nlumo_stm > 0) THEN
776 8 : ALLOCATE (unoccupied_orbs_stm(dft_control%nspins))
777 8 : ALLOCATE (unoccupied_evals_stm(dft_control%nspins))
778 : CALL make_lumo_gpw(qs_env, scf_env, unoccupied_orbs_stm, unoccupied_evals_stm, &
779 2 : nlumo_stm, nlumos)
780 : END IF
781 :
782 : CALL th_stm_image(qs_env, stm_section, particles, unoccupied_orbs_stm, &
783 6 : unoccupied_evals_stm)
784 :
785 6 : IF (nlumo_stm > 0) THEN
786 4 : DO ispin = 1, dft_control%nspins
787 4 : DEALLOCATE (unoccupied_evals_stm(ispin)%array)
788 : END DO
789 2 : DEALLOCATE (unoccupied_evals_stm)
790 2 : CALL cp_fm_release(unoccupied_orbs_stm)
791 : END IF
792 : END IF
793 : END IF
794 :
795 : ! Print coherent X-ray diffraction spectrum
796 10059 : CALL qs_scf_post_xray(input, dft_section, logger, qs_env, output_unit)
797 :
798 : ! Calculation of Electric Field Gradients
799 10059 : CALL qs_scf_post_efg(input, logger, qs_env)
800 :
801 : ! Calculation of ET
802 10059 : CALL qs_scf_post_et(input, qs_env, dft_control)
803 :
804 : ! Calculation of EPR Hyperfine Coupling Tensors
805 10059 : CALL qs_scf_post_epr(input, logger, qs_env)
806 :
807 : ! Calculation of properties needed for BASIS_MOLOPT optimizations
808 10059 : CALL qs_scf_post_molopt(input, logger, qs_env)
809 :
810 : ! Calculate ELF
811 10059 : CALL qs_scf_post_elf(input, logger, qs_env)
812 :
813 : ! Use Wannier90 interface
814 10059 : CALL wannier90_interface(input, logger, qs_env)
815 :
816 10059 : IF (my_do_mp2) THEN
817 : ! Get everything back
818 742 : DO ispin = 1, dft_control%nspins
819 742 : CALL dbcsr_add(rho_ao(ispin, 1)%matrix, matrix_p_mp2(ispin)%matrix, 1.0_dp, -1.0_dp)
820 : END DO
821 322 : CALL qs_rho_update_rho(rho, qs_env=qs_env)
822 322 : CALL qs_ks_did_change(qs_env%ks_env, rho_changed=.TRUE.)
823 : END IF
824 :
825 10059 : CALL timestop(handle)
826 :
827 20118 : END SUBROUTINE scf_post_calculation_gpw
828 :
829 : ! **************************************************************************************************
830 : !> \brief Gets the lumos, and eigenvalues for the lumos
831 : !> \param qs_env ...
832 : !> \param scf_env ...
833 : !> \param unoccupied_orbs ...
834 : !> \param unoccupied_evals ...
835 : !> \param nlumo ...
836 : !> \param nlumos ...
837 : ! **************************************************************************************************
838 34 : SUBROUTINE make_lumo_gpw(qs_env, scf_env, unoccupied_orbs, unoccupied_evals, nlumo, nlumos)
839 :
840 : TYPE(qs_environment_type), POINTER :: qs_env
841 : TYPE(qs_scf_env_type), POINTER :: scf_env
842 : TYPE(cp_fm_type), DIMENSION(:), INTENT(INOUT) :: unoccupied_orbs
843 : TYPE(cp_1d_r_p_type), DIMENSION(:), POINTER :: unoccupied_evals
844 : INTEGER, INTENT(IN) :: nlumo
845 : INTEGER, INTENT(OUT) :: nlumos
846 :
847 : CHARACTER(len=*), PARAMETER :: routineN = 'make_lumo_gpw'
848 :
849 : INTEGER :: handle, homo, ispin, n, nao, nmo, &
850 : output_unit
851 : TYPE(admm_type), POINTER :: admm_env
852 : TYPE(cp_blacs_env_type), POINTER :: blacs_env
853 : TYPE(cp_fm_struct_type), POINTER :: fm_struct_tmp
854 : TYPE(cp_fm_type), POINTER :: mo_coeff
855 : TYPE(cp_logger_type), POINTER :: logger
856 34 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: ks_rmpv, matrix_s
857 : TYPE(dft_control_type), POINTER :: dft_control
858 34 : TYPE(mo_set_type), DIMENSION(:), POINTER :: mos
859 : TYPE(mp_para_env_type), POINTER :: para_env
860 : TYPE(preconditioner_type), POINTER :: local_preconditioner
861 : TYPE(scf_control_type), POINTER :: scf_control
862 :
863 34 : CALL timeset(routineN, handle)
864 :
865 34 : NULLIFY (mos, ks_rmpv, scf_control, dft_control, admm_env, para_env, blacs_env)
866 : CALL get_qs_env(qs_env, &
867 : mos=mos, &
868 : matrix_ks=ks_rmpv, &
869 : scf_control=scf_control, &
870 : dft_control=dft_control, &
871 : matrix_s=matrix_s, &
872 : admm_env=admm_env, &
873 : para_env=para_env, &
874 34 : blacs_env=blacs_env)
875 :
876 34 : logger => cp_get_default_logger()
877 34 : output_unit = cp_logger_get_default_io_unit(logger)
878 :
879 84 : DO ispin = 1, dft_control%nspins
880 50 : NULLIFY (unoccupied_evals(ispin)%array)
881 : ! Always write eigenvalues
882 50 : IF (output_unit > 0) WRITE (output_unit, *) " "
883 50 : IF (output_unit > 0) WRITE (output_unit, *) " Lowest Eigenvalues of the unoccupied subspace spin ", ispin
884 50 : IF (output_unit > 0) WRITE (output_unit, FMT='(1X,A)') "-----------------------------------------------------"
885 50 : CALL get_mo_set(mo_set=mos(ispin), mo_coeff=mo_coeff, homo=homo, nao=nao, nmo=nmo)
886 50 : CALL cp_fm_get_info(mo_coeff, nrow_global=n)
887 50 : nlumos = MAX(1, MIN(nlumo, nao - nmo))
888 50 : IF (nlumo == -1) nlumos = nao - nmo
889 150 : ALLOCATE (unoccupied_evals(ispin)%array(nlumos))
890 : CALL cp_fm_struct_create(fm_struct_tmp, para_env=para_env, context=blacs_env, &
891 50 : nrow_global=n, ncol_global=nlumos)
892 50 : CALL cp_fm_create(unoccupied_orbs(ispin), fm_struct_tmp, name="lumos")
893 50 : CALL cp_fm_struct_release(fm_struct_tmp)
894 50 : CALL cp_fm_init_random(unoccupied_orbs(ispin), nlumos)
895 :
896 : ! the full_all preconditioner makes not much sense for lumos search
897 50 : NULLIFY (local_preconditioner)
898 50 : IF (ASSOCIATED(scf_env%ot_preconditioner)) THEN
899 26 : local_preconditioner => scf_env%ot_preconditioner(1)%preconditioner
900 : ! this one can for sure not be right (as it has to match a given C0)
901 26 : IF (local_preconditioner%in_use == ot_precond_full_all) THEN
902 4 : NULLIFY (local_preconditioner)
903 : END IF
904 : END IF
905 :
906 : ! If we do ADMM, we add have to modify the Kohn-Sham matrix
907 50 : IF (dft_control%do_admm) THEN
908 0 : CALL admm_correct_for_eigenvalues(ispin, admm_env, ks_rmpv(ispin)%matrix)
909 : END IF
910 :
911 : CALL ot_eigensolver(matrix_h=ks_rmpv(ispin)%matrix, matrix_s=matrix_s(1)%matrix, &
912 : matrix_c_fm=unoccupied_orbs(ispin), &
913 : matrix_orthogonal_space_fm=mo_coeff, &
914 : eps_gradient=scf_control%eps_lumos, &
915 : preconditioner=local_preconditioner, &
916 : iter_max=scf_control%max_iter_lumos, &
917 50 : size_ortho_space=nmo)
918 :
919 : CALL calculate_subspace_eigenvalues(unoccupied_orbs(ispin), ks_rmpv(ispin)%matrix, &
920 : unoccupied_evals(ispin)%array, scr=output_unit, &
921 50 : ionode=output_unit > 0)
922 :
923 : ! If we do ADMM, we restore the original Kohn-Sham matrix
924 134 : IF (dft_control%do_admm) THEN
925 0 : CALL admm_uncorrect_for_eigenvalues(ispin, admm_env, ks_rmpv(ispin)%matrix)
926 : END IF
927 :
928 : END DO
929 :
930 34 : CALL timestop(handle)
931 :
932 34 : END SUBROUTINE make_lumo_gpw
933 : ! **************************************************************************************************
934 : !> \brief Computes and Prints Atomic Charges with several methods
935 : !> \param input ...
936 : !> \param logger ...
937 : !> \param qs_env the qs_env in which the qs_env lives
938 : ! **************************************************************************************************
939 10059 : SUBROUTINE qs_scf_post_charges(input, logger, qs_env)
940 : TYPE(section_vals_type), POINTER :: input
941 : TYPE(cp_logger_type), POINTER :: logger
942 : TYPE(qs_environment_type), POINTER :: qs_env
943 :
944 : CHARACTER(len=*), PARAMETER :: routineN = 'qs_scf_post_charges'
945 :
946 : INTEGER :: handle, print_level, unit_nr
947 : LOGICAL :: do_kpoints, print_it
948 : TYPE(section_vals_type), POINTER :: density_fit_section, print_key
949 :
950 10059 : CALL timeset(routineN, handle)
951 :
952 10059 : CALL get_qs_env(qs_env=qs_env, do_kpoints=do_kpoints)
953 :
954 : ! Mulliken charges require no further computation and are printed from write_mo_free_results
955 :
956 : ! Compute the Lowdin charges
957 10059 : print_key => section_vals_get_subs_vals(input, "DFT%PRINT%LOWDIN")
958 10059 : IF (BTEST(cp_print_key_should_output(logger%iter_info, print_key), cp_p_file)) THEN
959 : unit_nr = cp_print_key_unit_nr(logger, input, "DFT%PRINT%LOWDIN", extension=".lowdin", &
960 82 : log_filename=.FALSE.)
961 82 : print_level = 1
962 82 : CALL section_vals_val_get(print_key, "PRINT_GOP", l_val=print_it)
963 82 : IF (print_it) print_level = 2
964 82 : CALL section_vals_val_get(print_key, "PRINT_ALL", l_val=print_it)
965 82 : IF (print_it) print_level = 3
966 82 : IF (do_kpoints) THEN
967 2 : CPWARN("Lowdin charges not implemented for k-point calculations!")
968 : ELSE
969 80 : CALL lowdin_population_analysis(qs_env, unit_nr, print_level)
970 : END IF
971 82 : CALL cp_print_key_finished_output(unit_nr, logger, input, "DFT%PRINT%LOWDIN")
972 : END IF
973 :
974 : ! Compute the RESP charges
975 10059 : CALL resp_fit(qs_env)
976 :
977 : ! Compute the Density Derived Atomic Point charges with the Bloechl scheme
978 10059 : print_key => section_vals_get_subs_vals(input, "PROPERTIES%FIT_CHARGE")
979 10059 : IF (BTEST(cp_print_key_should_output(logger%iter_info, print_key), cp_p_file)) THEN
980 : unit_nr = cp_print_key_unit_nr(logger, input, "PROPERTIES%FIT_CHARGE", extension=".Fitcharge", &
981 102 : log_filename=.FALSE.)
982 102 : density_fit_section => section_vals_get_subs_vals(input, "DFT%DENSITY_FITTING")
983 102 : CALL get_ddapc(qs_env, .FALSE., density_fit_section, iwc=unit_nr)
984 102 : CALL cp_print_key_finished_output(unit_nr, logger, input, "PROPERTIES%FIT_CHARGE")
985 : END IF
986 :
987 10059 : CALL timestop(handle)
988 :
989 10059 : END SUBROUTINE qs_scf_post_charges
990 :
991 : ! **************************************************************************************************
992 : !> \brief Computes and prints the Cube Files for MO
993 : !> \param input ...
994 : !> \param dft_section ...
995 : !> \param dft_control ...
996 : !> \param logger ...
997 : !> \param qs_env the qs_env in which the qs_env lives
998 : !> \param mo_coeff ...
999 : !> \param wf_g ...
1000 : !> \param wf_r ...
1001 : !> \param particles ...
1002 : !> \param homo ...
1003 : !> \param ispin ...
1004 : ! **************************************************************************************************
1005 146 : SUBROUTINE qs_scf_post_occ_cubes(input, dft_section, dft_control, logger, qs_env, &
1006 : mo_coeff, wf_g, wf_r, particles, homo, ispin)
1007 : TYPE(section_vals_type), POINTER :: input, dft_section
1008 : TYPE(dft_control_type), POINTER :: dft_control
1009 : TYPE(cp_logger_type), POINTER :: logger
1010 : TYPE(qs_environment_type), POINTER :: qs_env
1011 : TYPE(cp_fm_type), INTENT(IN) :: mo_coeff
1012 : TYPE(pw_c1d_gs_type), INTENT(INOUT) :: wf_g
1013 : TYPE(pw_r3d_rs_type), INTENT(INOUT) :: wf_r
1014 : TYPE(particle_list_type), POINTER :: particles
1015 : INTEGER, INTENT(IN) :: homo, ispin
1016 :
1017 : CHARACTER(len=*), PARAMETER :: routineN = 'qs_scf_post_occ_cubes'
1018 :
1019 : CHARACTER(LEN=default_path_length) :: filename, my_pos_cube, title
1020 : INTEGER :: handle, i, ir, ivector, n_rep, nhomo, &
1021 : nlist, unit_nr
1022 146 : INTEGER, DIMENSION(:), POINTER :: list, list_index
1023 : LOGICAL :: append_cube, mpi_io
1024 146 : TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
1025 : TYPE(cell_type), POINTER :: cell
1026 146 : TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
1027 : TYPE(pw_env_type), POINTER :: pw_env
1028 146 : TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
1029 :
1030 146 : CALL timeset(routineN, handle)
1031 :
1032 146 : NULLIFY (list_index)
1033 :
1034 : IF (BTEST(cp_print_key_should_output(logger%iter_info, dft_section, "PRINT%MO_CUBES") &
1035 146 : , cp_p_file) .AND. section_get_lval(dft_section, "PRINT%MO_CUBES%WRITE_CUBE")) THEN
1036 108 : nhomo = section_get_ival(dft_section, "PRINT%MO_CUBES%NHOMO")
1037 108 : append_cube = section_get_lval(dft_section, "PRINT%MO_CUBES%APPEND")
1038 108 : my_pos_cube = "REWIND"
1039 108 : IF (append_cube) THEN
1040 0 : my_pos_cube = "APPEND"
1041 : END IF
1042 108 : CALL section_vals_val_get(dft_section, "PRINT%MO_CUBES%HOMO_LIST", n_rep_val=n_rep)
1043 108 : IF (n_rep > 0) THEN ! write the cubes of the list
1044 0 : nlist = 0
1045 0 : DO ir = 1, n_rep
1046 0 : NULLIFY (list)
1047 : CALL section_vals_val_get(dft_section, "PRINT%MO_CUBES%HOMO_LIST", i_rep_val=ir, &
1048 0 : i_vals=list)
1049 0 : IF (ASSOCIATED(list)) THEN
1050 0 : CALL reallocate(list_index, 1, nlist + SIZE(list))
1051 0 : DO i = 1, SIZE(list)
1052 0 : list_index(i + nlist) = list(i)
1053 : END DO
1054 0 : nlist = nlist + SIZE(list)
1055 : END IF
1056 : END DO
1057 : ELSE
1058 :
1059 108 : IF (nhomo == -1) nhomo = homo
1060 108 : nlist = homo - MAX(1, homo - nhomo + 1) + 1
1061 324 : ALLOCATE (list_index(nlist))
1062 220 : DO i = 1, nlist
1063 220 : list_index(i) = MAX(1, homo - nhomo + 1) + i - 1
1064 : END DO
1065 : END IF
1066 220 : DO i = 1, nlist
1067 112 : ivector = list_index(i)
1068 : CALL get_qs_env(qs_env=qs_env, &
1069 : atomic_kind_set=atomic_kind_set, &
1070 : qs_kind_set=qs_kind_set, &
1071 : cell=cell, &
1072 : particle_set=particle_set, &
1073 112 : pw_env=pw_env)
1074 : CALL calculate_wavefunction(mo_coeff, ivector, wf_r, wf_g, atomic_kind_set, qs_kind_set, &
1075 112 : cell, dft_control, particle_set, pw_env)
1076 112 : WRITE (filename, '(a4,I5.5,a1,I1.1)') "WFN_", ivector, "_", ispin
1077 112 : mpi_io = .TRUE.
1078 : unit_nr = cp_print_key_unit_nr(logger, input, "DFT%PRINT%MO_CUBES", extension=".cube", &
1079 : middle_name=TRIM(filename), file_position=my_pos_cube, log_filename=.FALSE., &
1080 112 : mpi_io=mpi_io)
1081 112 : WRITE (title, *) "WAVEFUNCTION ", ivector, " spin ", ispin, " i.e. HOMO - ", ivector - homo
1082 : CALL cp_pw_to_cube(wf_r, unit_nr, title, particles=particles, &
1083 : stride=section_get_ivals(dft_section, "PRINT%MO_CUBES%STRIDE"), &
1084 : max_file_size_mb=section_get_rval(dft_section, "PRINT%MO_CUBES%MAX_FILE_SIZE_MB"), &
1085 112 : mpi_io=mpi_io)
1086 220 : CALL cp_print_key_finished_output(unit_nr, logger, input, "DFT%PRINT%MO_CUBES", mpi_io=mpi_io)
1087 : END DO
1088 108 : IF (ASSOCIATED(list_index)) DEALLOCATE (list_index)
1089 : END IF
1090 :
1091 146 : CALL timestop(handle)
1092 :
1093 146 : END SUBROUTINE qs_scf_post_occ_cubes
1094 :
1095 : ! **************************************************************************************************
1096 : !> \brief Computes and prints the Cube Files for MO
1097 : !> \param input ...
1098 : !> \param dft_section ...
1099 : !> \param dft_control ...
1100 : !> \param logger ...
1101 : !> \param qs_env the qs_env in which the qs_env lives
1102 : !> \param unoccupied_orbs ...
1103 : !> \param wf_g ...
1104 : !> \param wf_r ...
1105 : !> \param particles ...
1106 : !> \param nlumos ...
1107 : !> \param homo ...
1108 : !> \param ispin ...
1109 : !> \param lumo ...
1110 : ! **************************************************************************************************
1111 146 : SUBROUTINE qs_scf_post_unocc_cubes(input, dft_section, dft_control, logger, qs_env, &
1112 : unoccupied_orbs, wf_g, wf_r, particles, nlumos, homo, ispin, lumo)
1113 :
1114 : TYPE(section_vals_type), POINTER :: input, dft_section
1115 : TYPE(dft_control_type), POINTER :: dft_control
1116 : TYPE(cp_logger_type), POINTER :: logger
1117 : TYPE(qs_environment_type), POINTER :: qs_env
1118 : TYPE(cp_fm_type), INTENT(IN) :: unoccupied_orbs
1119 : TYPE(pw_c1d_gs_type), INTENT(INOUT) :: wf_g
1120 : TYPE(pw_r3d_rs_type), INTENT(INOUT) :: wf_r
1121 : TYPE(particle_list_type), POINTER :: particles
1122 : INTEGER, INTENT(IN) :: nlumos, homo, ispin
1123 : INTEGER, INTENT(IN), OPTIONAL :: lumo
1124 :
1125 : CHARACTER(len=*), PARAMETER :: routineN = 'qs_scf_post_unocc_cubes'
1126 :
1127 : CHARACTER(LEN=default_path_length) :: filename, my_pos_cube, title
1128 : INTEGER :: handle, ifirst, index_mo, ivector, &
1129 : unit_nr
1130 : LOGICAL :: append_cube, mpi_io
1131 146 : TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
1132 : TYPE(cell_type), POINTER :: cell
1133 146 : TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
1134 : TYPE(pw_env_type), POINTER :: pw_env
1135 146 : TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
1136 :
1137 146 : CALL timeset(routineN, handle)
1138 :
1139 : IF (BTEST(cp_print_key_should_output(logger%iter_info, dft_section, "PRINT%MO_CUBES"), cp_p_file) &
1140 146 : .AND. section_get_lval(dft_section, "PRINT%MO_CUBES%WRITE_CUBE")) THEN
1141 108 : NULLIFY (qs_kind_set, particle_set, pw_env, cell)
1142 108 : append_cube = section_get_lval(dft_section, "PRINT%MO_CUBES%APPEND")
1143 108 : my_pos_cube = "REWIND"
1144 108 : IF (append_cube) THEN
1145 0 : my_pos_cube = "APPEND"
1146 : END IF
1147 108 : ifirst = 1
1148 108 : IF (PRESENT(lumo)) ifirst = lumo
1149 250 : DO ivector = ifirst, ifirst + nlumos - 1
1150 : CALL get_qs_env(qs_env=qs_env, &
1151 : atomic_kind_set=atomic_kind_set, &
1152 : qs_kind_set=qs_kind_set, &
1153 : cell=cell, &
1154 : particle_set=particle_set, &
1155 142 : pw_env=pw_env)
1156 : CALL calculate_wavefunction(unoccupied_orbs, ivector, wf_r, wf_g, atomic_kind_set, &
1157 142 : qs_kind_set, cell, dft_control, particle_set, pw_env)
1158 :
1159 142 : IF (ifirst == 1) THEN
1160 130 : index_mo = homo + ivector
1161 : ELSE
1162 12 : index_mo = ivector
1163 : END IF
1164 142 : WRITE (filename, '(a4,I5.5,a1,I1.1)') "WFN_", index_mo, "_", ispin
1165 142 : mpi_io = .TRUE.
1166 :
1167 : unit_nr = cp_print_key_unit_nr(logger, input, "DFT%PRINT%MO_CUBES", extension=".cube", &
1168 : middle_name=TRIM(filename), file_position=my_pos_cube, log_filename=.FALSE., &
1169 142 : mpi_io=mpi_io)
1170 142 : WRITE (title, *) "WAVEFUNCTION ", index_mo, " spin ", ispin, " i.e. LUMO + ", ifirst + ivector - 2
1171 : CALL cp_pw_to_cube(wf_r, unit_nr, title, particles=particles, &
1172 : stride=section_get_ivals(dft_section, "PRINT%MO_CUBES%STRIDE"), &
1173 : max_file_size_mb=section_get_rval(dft_section, "PRINT%MO_CUBES%MAX_FILE_SIZE_MB"), &
1174 142 : mpi_io=mpi_io)
1175 250 : CALL cp_print_key_finished_output(unit_nr, logger, input, "DFT%PRINT%MO_CUBES", mpi_io=mpi_io)
1176 : END DO
1177 : END IF
1178 :
1179 146 : CALL timestop(handle)
1180 :
1181 146 : END SUBROUTINE qs_scf_post_unocc_cubes
1182 :
1183 : ! **************************************************************************************************
1184 : !> \brief Computes and prints electric moments
1185 : !> \param input ...
1186 : !> \param logger ...
1187 : !> \param qs_env the qs_env in which the qs_env lives
1188 : !> \param output_unit ...
1189 : ! **************************************************************************************************
1190 11245 : SUBROUTINE qs_scf_post_moments(input, logger, qs_env, output_unit)
1191 : TYPE(section_vals_type), POINTER :: input
1192 : TYPE(cp_logger_type), POINTER :: logger
1193 : TYPE(qs_environment_type), POINTER :: qs_env
1194 : INTEGER, INTENT(IN) :: output_unit
1195 :
1196 : CHARACTER(len=*), PARAMETER :: routineN = 'qs_scf_post_moments'
1197 :
1198 : CHARACTER(LEN=default_path_length) :: filename
1199 : INTEGER :: handle, maxmom, reference, unit_nr
1200 : LOGICAL :: com_nl, do_kpoints, magnetic, periodic, &
1201 : second_ref_point, vel_reprs
1202 11245 : REAL(KIND=dp), DIMENSION(:), POINTER :: ref_point
1203 : TYPE(section_vals_type), POINTER :: print_key
1204 :
1205 11245 : CALL timeset(routineN, handle)
1206 :
1207 : print_key => section_vals_get_subs_vals(section_vals=input, &
1208 11245 : subsection_name="DFT%PRINT%MOMENTS")
1209 :
1210 11245 : IF (BTEST(cp_print_key_should_output(logger%iter_info, print_key), cp_p_file)) THEN
1211 :
1212 : maxmom = section_get_ival(section_vals=input, &
1213 1276 : keyword_name="DFT%PRINT%MOMENTS%MAX_MOMENT")
1214 : periodic = section_get_lval(section_vals=input, &
1215 1276 : keyword_name="DFT%PRINT%MOMENTS%PERIODIC")
1216 : reference = section_get_ival(section_vals=input, &
1217 1276 : keyword_name="DFT%PRINT%MOMENTS%REFERENCE")
1218 : magnetic = section_get_lval(section_vals=input, &
1219 1276 : keyword_name="DFT%PRINT%MOMENTS%MAGNETIC")
1220 : vel_reprs = section_get_lval(section_vals=input, &
1221 1276 : keyword_name="DFT%PRINT%MOMENTS%VEL_REPRS")
1222 : com_nl = section_get_lval(section_vals=input, &
1223 1276 : keyword_name="DFT%PRINT%MOMENTS%COM_NL")
1224 : second_ref_point = section_get_lval(section_vals=input, &
1225 1276 : keyword_name="DFT%PRINT%MOMENTS%SECOND_REFERENCE_POINT")
1226 :
1227 1276 : NULLIFY (ref_point)
1228 1276 : CALL section_vals_val_get(input, "DFT%PRINT%MOMENTS%REF_POINT", r_vals=ref_point)
1229 : unit_nr = cp_print_key_unit_nr(logger=logger, basis_section=input, &
1230 : print_key_path="DFT%PRINT%MOMENTS", extension=".dat", &
1231 1276 : middle_name="moments", log_filename=.FALSE.)
1232 :
1233 1276 : IF (output_unit > 0) THEN
1234 648 : IF (unit_nr /= output_unit) THEN
1235 33 : INQUIRE (UNIT=unit_nr, NAME=filename)
1236 : WRITE (UNIT=output_unit, FMT="(/,T2,A,2(/,T3,A),/)") &
1237 33 : "MOMENTS", "The electric/magnetic moments are written to file:", &
1238 66 : TRIM(filename)
1239 : ELSE
1240 615 : WRITE (UNIT=output_unit, FMT="(/,T2,A)") "ELECTRIC/MAGNETIC MOMENTS"
1241 : END IF
1242 : END IF
1243 :
1244 1276 : CALL get_qs_env(qs_env, do_kpoints=do_kpoints)
1245 :
1246 1276 : IF (do_kpoints) THEN
1247 8 : CALL qs_moment_kpoints(qs_env, maxmom, reference, ref_point, unit_nr)
1248 : ELSE
1249 1268 : IF (periodic) THEN
1250 472 : CALL qs_moment_berry_phase(qs_env, magnetic, maxmom, reference, ref_point, unit_nr)
1251 : ELSE
1252 796 : CALL qs_moment_locop(qs_env, magnetic, maxmom, reference, ref_point, unit_nr, vel_reprs, com_nl)
1253 : END IF
1254 : END IF
1255 :
1256 : CALL cp_print_key_finished_output(unit_nr=unit_nr, logger=logger, &
1257 1276 : basis_section=input, print_key_path="DFT%PRINT%MOMENTS")
1258 :
1259 1276 : IF (second_ref_point) THEN
1260 : reference = section_get_ival(section_vals=input, &
1261 0 : keyword_name="DFT%PRINT%MOMENTS%REFERENCE_2")
1262 :
1263 0 : NULLIFY (ref_point)
1264 0 : CALL section_vals_val_get(input, "DFT%PRINT%MOMENTS%REF_POINT_2", r_vals=ref_point)
1265 : unit_nr = cp_print_key_unit_nr(logger=logger, basis_section=input, &
1266 : print_key_path="DFT%PRINT%MOMENTS", extension=".dat", &
1267 0 : middle_name="moments_refpoint_2", log_filename=.FALSE.)
1268 :
1269 0 : IF (output_unit > 0) THEN
1270 0 : IF (unit_nr /= output_unit) THEN
1271 0 : INQUIRE (UNIT=unit_nr, NAME=filename)
1272 : WRITE (UNIT=output_unit, FMT="(/,T2,A,2(/,T3,A),/)") &
1273 0 : "MOMENTS", "The electric/magnetic moments for the second reference point are written to file:", &
1274 0 : TRIM(filename)
1275 : ELSE
1276 0 : WRITE (UNIT=output_unit, FMT="(/,T2,A)") "ELECTRIC/MAGNETIC MOMENTS"
1277 : END IF
1278 : END IF
1279 0 : IF (do_kpoints) THEN
1280 0 : CALL qs_moment_kpoints(qs_env, maxmom, reference, ref_point, unit_nr)
1281 : ELSE
1282 0 : IF (periodic) THEN
1283 0 : CALL qs_moment_berry_phase(qs_env, magnetic, maxmom, reference, ref_point, unit_nr)
1284 : ELSE
1285 0 : CALL qs_moment_locop(qs_env, magnetic, maxmom, reference, ref_point, unit_nr, vel_reprs, com_nl)
1286 : END IF
1287 : END IF
1288 : CALL cp_print_key_finished_output(unit_nr=unit_nr, logger=logger, &
1289 0 : basis_section=input, print_key_path="DFT%PRINT%MOMENTS")
1290 : END IF
1291 :
1292 : END IF
1293 :
1294 11245 : CALL timestop(handle)
1295 :
1296 11245 : END SUBROUTINE qs_scf_post_moments
1297 :
1298 : ! **************************************************************************************************
1299 : !> \brief Computes and prints the X-ray diffraction spectrum.
1300 : !> \param input ...
1301 : !> \param dft_section ...
1302 : !> \param logger ...
1303 : !> \param qs_env the qs_env in which the qs_env lives
1304 : !> \param output_unit ...
1305 : ! **************************************************************************************************
1306 10059 : SUBROUTINE qs_scf_post_xray(input, dft_section, logger, qs_env, output_unit)
1307 :
1308 : TYPE(section_vals_type), POINTER :: input, dft_section
1309 : TYPE(cp_logger_type), POINTER :: logger
1310 : TYPE(qs_environment_type), POINTER :: qs_env
1311 : INTEGER, INTENT(IN) :: output_unit
1312 :
1313 : CHARACTER(LEN=*), PARAMETER :: routineN = 'qs_scf_post_xray'
1314 :
1315 : CHARACTER(LEN=default_path_length) :: filename
1316 : INTEGER :: handle, unit_nr
1317 : REAL(KIND=dp) :: q_max
1318 : TYPE(section_vals_type), POINTER :: print_key
1319 :
1320 10059 : CALL timeset(routineN, handle)
1321 :
1322 : print_key => section_vals_get_subs_vals(section_vals=input, &
1323 10059 : subsection_name="DFT%PRINT%XRAY_DIFFRACTION_SPECTRUM")
1324 :
1325 10059 : IF (BTEST(cp_print_key_should_output(logger%iter_info, print_key), cp_p_file)) THEN
1326 : q_max = section_get_rval(section_vals=dft_section, &
1327 30 : keyword_name="PRINT%XRAY_DIFFRACTION_SPECTRUM%Q_MAX")
1328 : unit_nr = cp_print_key_unit_nr(logger=logger, &
1329 : basis_section=input, &
1330 : print_key_path="DFT%PRINT%XRAY_DIFFRACTION_SPECTRUM", &
1331 : extension=".dat", &
1332 : middle_name="xrd", &
1333 30 : log_filename=.FALSE.)
1334 30 : IF (output_unit > 0) THEN
1335 15 : INQUIRE (UNIT=unit_nr, NAME=filename)
1336 : WRITE (UNIT=output_unit, FMT="(/,/,T2,A)") &
1337 15 : "X-RAY DIFFRACTION SPECTRUM"
1338 15 : IF (unit_nr /= output_unit) THEN
1339 : WRITE (UNIT=output_unit, FMT="(/,T3,A,/,/,T3,A,/)") &
1340 14 : "The coherent X-ray diffraction spectrum is written to the file:", &
1341 28 : TRIM(filename)
1342 : END IF
1343 : END IF
1344 : CALL xray_diffraction_spectrum(qs_env=qs_env, &
1345 : unit_number=unit_nr, &
1346 30 : q_max=q_max)
1347 : CALL cp_print_key_finished_output(unit_nr=unit_nr, &
1348 : logger=logger, &
1349 : basis_section=input, &
1350 30 : print_key_path="DFT%PRINT%XRAY_DIFFRACTION_SPECTRUM")
1351 : END IF
1352 :
1353 10059 : CALL timestop(handle)
1354 :
1355 10059 : END SUBROUTINE qs_scf_post_xray
1356 :
1357 : ! **************************************************************************************************
1358 : !> \brief Computes and prints Electric Field Gradient
1359 : !> \param input ...
1360 : !> \param logger ...
1361 : !> \param qs_env the qs_env in which the qs_env lives
1362 : ! **************************************************************************************************
1363 10059 : SUBROUTINE qs_scf_post_efg(input, logger, qs_env)
1364 : TYPE(section_vals_type), POINTER :: input
1365 : TYPE(cp_logger_type), POINTER :: logger
1366 : TYPE(qs_environment_type), POINTER :: qs_env
1367 :
1368 : CHARACTER(len=*), PARAMETER :: routineN = 'qs_scf_post_efg'
1369 :
1370 : INTEGER :: handle
1371 : TYPE(section_vals_type), POINTER :: print_key
1372 :
1373 10059 : CALL timeset(routineN, handle)
1374 :
1375 : print_key => section_vals_get_subs_vals(section_vals=input, &
1376 10059 : subsection_name="DFT%PRINT%ELECTRIC_FIELD_GRADIENT")
1377 10059 : IF (BTEST(cp_print_key_should_output(logger%iter_info, print_key), &
1378 : cp_p_file)) THEN
1379 30 : CALL qs_efg_calc(qs_env=qs_env)
1380 : END IF
1381 :
1382 10059 : CALL timestop(handle)
1383 :
1384 10059 : END SUBROUTINE qs_scf_post_efg
1385 :
1386 : ! **************************************************************************************************
1387 : !> \brief Computes the Electron Transfer Coupling matrix element
1388 : !> \param input ...
1389 : !> \param qs_env the qs_env in which the qs_env lives
1390 : !> \param dft_control ...
1391 : ! **************************************************************************************************
1392 20118 : SUBROUTINE qs_scf_post_et(input, qs_env, dft_control)
1393 : TYPE(section_vals_type), POINTER :: input
1394 : TYPE(qs_environment_type), POINTER :: qs_env
1395 : TYPE(dft_control_type), POINTER :: dft_control
1396 :
1397 : CHARACTER(len=*), PARAMETER :: routineN = 'qs_scf_post_et'
1398 :
1399 : INTEGER :: handle, ispin
1400 : LOGICAL :: do_et
1401 10059 : TYPE(cp_fm_type), DIMENSION(:), POINTER :: my_mos
1402 : TYPE(section_vals_type), POINTER :: et_section
1403 :
1404 10059 : CALL timeset(routineN, handle)
1405 :
1406 : do_et = .FALSE.
1407 10059 : et_section => section_vals_get_subs_vals(input, "PROPERTIES%ET_COUPLING")
1408 10059 : CALL section_vals_get(et_section, explicit=do_et)
1409 10059 : IF (do_et) THEN
1410 10 : IF (qs_env%et_coupling%first_run) THEN
1411 10 : NULLIFY (my_mos)
1412 50 : ALLOCATE (my_mos(dft_control%nspins))
1413 50 : ALLOCATE (qs_env%et_coupling%et_mo_coeff(dft_control%nspins))
1414 30 : DO ispin = 1, dft_control%nspins
1415 : CALL cp_fm_create(matrix=my_mos(ispin), &
1416 : matrix_struct=qs_env%mos(ispin)%mo_coeff%matrix_struct, &
1417 20 : name="FIRST_RUN_COEFF"//TRIM(ADJUSTL(cp_to_string(ispin)))//"MATRIX")
1418 : CALL cp_fm_to_fm(qs_env%mos(ispin)%mo_coeff, &
1419 30 : my_mos(ispin))
1420 : END DO
1421 10 : CALL set_et_coupling_type(qs_env%et_coupling, et_mo_coeff=my_mos)
1422 10 : DEALLOCATE (my_mos)
1423 : END IF
1424 : END IF
1425 :
1426 10059 : CALL timestop(handle)
1427 :
1428 10059 : END SUBROUTINE qs_scf_post_et
1429 :
1430 : ! **************************************************************************************************
1431 : !> \brief compute the electron localization function
1432 : !>
1433 : !> \param input ...
1434 : !> \param logger ...
1435 : !> \param qs_env ...
1436 : !> \par History
1437 : !> 2012-07 Created [MI]
1438 : ! **************************************************************************************************
1439 10059 : SUBROUTINE qs_scf_post_elf(input, logger, qs_env)
1440 : TYPE(section_vals_type), POINTER :: input
1441 : TYPE(cp_logger_type), POINTER :: logger
1442 : TYPE(qs_environment_type), POINTER :: qs_env
1443 :
1444 : CHARACTER(len=*), PARAMETER :: routineN = 'qs_scf_post_elf'
1445 :
1446 : CHARACTER(LEN=default_path_length) :: filename, mpi_filename, my_pos_cube, &
1447 : title
1448 : INTEGER :: handle, ispin, output_unit, unit_nr
1449 : LOGICAL :: append_cube, gapw, mpi_io
1450 : REAL(dp) :: rho_cutoff
1451 : TYPE(dft_control_type), POINTER :: dft_control
1452 : TYPE(particle_list_type), POINTER :: particles
1453 : TYPE(pw_env_type), POINTER :: pw_env
1454 10059 : TYPE(pw_pool_p_type), DIMENSION(:), POINTER :: pw_pools
1455 : TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
1456 10059 : TYPE(pw_r3d_rs_type), ALLOCATABLE, DIMENSION(:) :: elf_r
1457 : TYPE(qs_subsys_type), POINTER :: subsys
1458 : TYPE(section_vals_type), POINTER :: elf_section
1459 :
1460 10059 : CALL timeset(routineN, handle)
1461 10059 : output_unit = cp_logger_get_default_io_unit(logger)
1462 :
1463 10059 : elf_section => section_vals_get_subs_vals(input, "DFT%PRINT%ELF_CUBE")
1464 10059 : IF (BTEST(cp_print_key_should_output(logger%iter_info, input, &
1465 : "DFT%PRINT%ELF_CUBE"), cp_p_file)) THEN
1466 :
1467 80 : NULLIFY (dft_control, pw_env, auxbas_pw_pool, pw_pools, particles, subsys)
1468 80 : CALL get_qs_env(qs_env, dft_control=dft_control, pw_env=pw_env, subsys=subsys)
1469 80 : CALL qs_subsys_get(subsys, particles=particles)
1470 :
1471 80 : gapw = dft_control%qs_control%gapw
1472 80 : IF (.NOT. gapw) THEN
1473 : ! allocate
1474 322 : ALLOCATE (elf_r(dft_control%nspins))
1475 : CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool, &
1476 80 : pw_pools=pw_pools)
1477 162 : DO ispin = 1, dft_control%nspins
1478 82 : CALL auxbas_pw_pool%create_pw(elf_r(ispin))
1479 162 : CALL pw_zero(elf_r(ispin))
1480 : END DO
1481 :
1482 80 : IF (output_unit > 0) THEN
1483 : WRITE (UNIT=output_unit, FMT="(/,T15,A,/)") &
1484 40 : " ----- ELF is computed on the real space grid -----"
1485 : END IF
1486 80 : rho_cutoff = section_get_rval(elf_section, "density_cutoff")
1487 80 : CALL qs_elf_calc(qs_env, elf_r, rho_cutoff)
1488 :
1489 : ! write ELF into cube file
1490 80 : append_cube = section_get_lval(elf_section, "APPEND")
1491 80 : my_pos_cube = "REWIND"
1492 80 : IF (append_cube) THEN
1493 0 : my_pos_cube = "APPEND"
1494 : END IF
1495 :
1496 162 : DO ispin = 1, dft_control%nspins
1497 82 : WRITE (filename, '(a5,I1.1)') "ELF_S", ispin
1498 82 : WRITE (title, *) "ELF spin ", ispin
1499 82 : mpi_io = .TRUE.
1500 : unit_nr = cp_print_key_unit_nr(logger, input, "DFT%PRINT%ELF_CUBE", extension=".cube", &
1501 : middle_name=TRIM(filename), file_position=my_pos_cube, log_filename=.FALSE., &
1502 82 : mpi_io=mpi_io, fout=mpi_filename)
1503 82 : IF (output_unit > 0) THEN
1504 41 : IF (.NOT. mpi_io) THEN
1505 0 : INQUIRE (UNIT=unit_nr, NAME=filename)
1506 : ELSE
1507 41 : filename = mpi_filename
1508 : END IF
1509 : WRITE (UNIT=output_unit, FMT="(/,T2,A,/,/,T2,A)") &
1510 41 : "ELF is written in cube file format to the file:", &
1511 82 : TRIM(filename)
1512 : END IF
1513 :
1514 : CALL cp_pw_to_cube(elf_r(ispin), unit_nr, title, particles=particles, &
1515 82 : stride=section_get_ivals(elf_section, "STRIDE"), mpi_io=mpi_io)
1516 82 : CALL cp_print_key_finished_output(unit_nr, logger, input, "DFT%PRINT%ELF_CUBE", mpi_io=mpi_io)
1517 :
1518 162 : CALL auxbas_pw_pool%give_back_pw(elf_r(ispin))
1519 : END DO
1520 :
1521 : ! deallocate
1522 80 : DEALLOCATE (elf_r)
1523 :
1524 : ELSE
1525 : ! not implemented
1526 0 : CPWARN("ELF not implemented for GAPW calculations!")
1527 : END IF
1528 :
1529 : END IF ! print key
1530 :
1531 10059 : CALL timestop(handle)
1532 :
1533 20118 : END SUBROUTINE qs_scf_post_elf
1534 :
1535 : ! **************************************************************************************************
1536 : !> \brief computes the condition number of the overlap matrix and
1537 : !> prints the value of the total energy. This is needed
1538 : !> for BASIS_MOLOPT optimizations
1539 : !> \param input ...
1540 : !> \param logger ...
1541 : !> \param qs_env the qs_env in which the qs_env lives
1542 : !> \par History
1543 : !> 2007-07 Created [Joost VandeVondele]
1544 : ! **************************************************************************************************
1545 10059 : SUBROUTINE qs_scf_post_molopt(input, logger, qs_env)
1546 : TYPE(section_vals_type), POINTER :: input
1547 : TYPE(cp_logger_type), POINTER :: logger
1548 : TYPE(qs_environment_type), POINTER :: qs_env
1549 :
1550 : CHARACTER(len=*), PARAMETER :: routineN = 'qs_scf_post_molopt'
1551 :
1552 : INTEGER :: handle, nao, unit_nr
1553 : REAL(KIND=dp) :: S_cond_number
1554 10059 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:) :: eigenvalues
1555 : TYPE(cp_fm_struct_type), POINTER :: ao_ao_fmstruct
1556 : TYPE(cp_fm_type) :: fm_s, fm_work
1557 : TYPE(cp_fm_type), POINTER :: mo_coeff
1558 10059 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_s
1559 10059 : TYPE(mo_set_type), DIMENSION(:), POINTER :: mos
1560 : TYPE(qs_energy_type), POINTER :: energy
1561 : TYPE(section_vals_type), POINTER :: print_key
1562 :
1563 10059 : CALL timeset(routineN, handle)
1564 :
1565 : print_key => section_vals_get_subs_vals(section_vals=input, &
1566 10059 : subsection_name="DFT%PRINT%BASIS_MOLOPT_QUANTITIES")
1567 10059 : IF (BTEST(cp_print_key_should_output(logger%iter_info, print_key), &
1568 : cp_p_file)) THEN
1569 :
1570 28 : CALL get_qs_env(qs_env, energy=energy, matrix_s=matrix_s, mos=mos)
1571 :
1572 : ! set up the two needed full matrices, using mo_coeff as a template
1573 28 : CALL get_mo_set(mo_set=mos(1), mo_coeff=mo_coeff, nao=nao)
1574 : CALL cp_fm_struct_create(fmstruct=ao_ao_fmstruct, &
1575 : nrow_global=nao, ncol_global=nao, &
1576 28 : template_fmstruct=mo_coeff%matrix_struct)
1577 : CALL cp_fm_create(fm_s, matrix_struct=ao_ao_fmstruct, &
1578 28 : name="fm_s")
1579 : CALL cp_fm_create(fm_work, matrix_struct=ao_ao_fmstruct, &
1580 28 : name="fm_work")
1581 28 : CALL cp_fm_struct_release(ao_ao_fmstruct)
1582 84 : ALLOCATE (eigenvalues(nao))
1583 :
1584 28 : CALL copy_dbcsr_to_fm(matrix_s(1)%matrix, fm_s)
1585 28 : CALL choose_eigv_solver(fm_s, fm_work, eigenvalues)
1586 :
1587 28 : CALL cp_fm_release(fm_s)
1588 28 : CALL cp_fm_release(fm_work)
1589 :
1590 1048 : S_cond_number = MAXVAL(ABS(eigenvalues))/MAX(MINVAL(ABS(eigenvalues)), EPSILON(0.0_dp))
1591 :
1592 : unit_nr = cp_print_key_unit_nr(logger, input, "DFT%PRINT%BASIS_MOLOPT_QUANTITIES", &
1593 28 : extension=".molopt")
1594 :
1595 28 : IF (unit_nr > 0) THEN
1596 : ! please keep this format fixed, needs to be grepable for molopt
1597 : ! optimizations
1598 14 : WRITE (unit_nr, '(T2,A28,2A25)') "", "Tot. Ener.", "S Cond. Numb."
1599 14 : WRITE (unit_nr, '(T2,A28,2E25.17)') "BASIS_MOLOPT_QUANTITIES", energy%total, S_cond_number
1600 : END IF
1601 :
1602 : CALL cp_print_key_finished_output(unit_nr, logger, input, &
1603 84 : "DFT%PRINT%BASIS_MOLOPT_QUANTITIES")
1604 :
1605 : END IF
1606 :
1607 10059 : CALL timestop(handle)
1608 :
1609 20118 : END SUBROUTINE qs_scf_post_molopt
1610 :
1611 : ! **************************************************************************************************
1612 : !> \brief Dumps EPR
1613 : !> \param input ...
1614 : !> \param logger ...
1615 : !> \param qs_env the qs_env in which the qs_env lives
1616 : ! **************************************************************************************************
1617 10059 : SUBROUTINE qs_scf_post_epr(input, logger, qs_env)
1618 : TYPE(section_vals_type), POINTER :: input
1619 : TYPE(cp_logger_type), POINTER :: logger
1620 : TYPE(qs_environment_type), POINTER :: qs_env
1621 :
1622 : CHARACTER(len=*), PARAMETER :: routineN = 'qs_scf_post_epr'
1623 :
1624 : INTEGER :: handle
1625 : TYPE(section_vals_type), POINTER :: print_key
1626 :
1627 10059 : CALL timeset(routineN, handle)
1628 :
1629 : print_key => section_vals_get_subs_vals(section_vals=input, &
1630 10059 : subsection_name="DFT%PRINT%HYPERFINE_COUPLING_TENSOR")
1631 10059 : IF (BTEST(cp_print_key_should_output(logger%iter_info, print_key), &
1632 : cp_p_file)) THEN
1633 30 : CALL qs_epr_hyp_calc(qs_env=qs_env)
1634 : END IF
1635 :
1636 10059 : CALL timestop(handle)
1637 :
1638 10059 : END SUBROUTINE qs_scf_post_epr
1639 :
1640 : ! **************************************************************************************************
1641 : !> \brief Interface routine to trigger writing of results available from normal
1642 : !> SCF. Can write MO-dependent and MO free results (needed for call from
1643 : !> the linear scaling code)
1644 : !> \param qs_env the qs_env in which the qs_env lives
1645 : !> \param scf_env ...
1646 : ! **************************************************************************************************
1647 10059 : SUBROUTINE write_available_results(qs_env, scf_env)
1648 : TYPE(qs_environment_type), POINTER :: qs_env
1649 : TYPE(qs_scf_env_type), OPTIONAL, POINTER :: scf_env
1650 :
1651 : CHARACTER(len=*), PARAMETER :: routineN = 'write_available_results'
1652 :
1653 : INTEGER :: handle
1654 :
1655 10059 : CALL timeset(routineN, handle)
1656 :
1657 : ! those properties that require MOs (not suitable density matrix based methods)
1658 10059 : CALL write_mo_dependent_results(qs_env, scf_env)
1659 :
1660 : ! those that depend only on the density matrix, they should be linear scaling in their implementation
1661 10059 : CALL write_mo_free_results(qs_env)
1662 :
1663 10059 : CALL timestop(handle)
1664 :
1665 10059 : END SUBROUTINE write_available_results
1666 :
1667 : ! **************************************************************************************************
1668 : !> \brief Write QS results available if MO's are present (if switched on through the print_keys)
1669 : !> Writes only MO dependent results. Split is necessary as ls_scf does not
1670 : !> provide MO's
1671 : !> \param qs_env the qs_env in which the qs_env lives
1672 : !> \param scf_env ...
1673 : ! **************************************************************************************************
1674 10371 : SUBROUTINE write_mo_dependent_results(qs_env, scf_env)
1675 : TYPE(qs_environment_type), POINTER :: qs_env
1676 : TYPE(qs_scf_env_type), OPTIONAL, POINTER :: scf_env
1677 :
1678 : CHARACTER(len=*), PARAMETER :: routineN = 'write_mo_dependent_results'
1679 :
1680 : INTEGER :: handle, homo, ispin, nmo, output_unit
1681 : LOGICAL :: all_equal, do_kpoints, explicit
1682 : REAL(KIND=dp) :: maxocc, s_square, s_square_ideal, &
1683 : total_abs_spin_dens, total_spin_dens
1684 10371 : REAL(KIND=dp), DIMENSION(:), POINTER :: mo_eigenvalues, occupation_numbers
1685 : TYPE(admm_type), POINTER :: admm_env
1686 10371 : TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
1687 : TYPE(cell_type), POINTER :: cell
1688 : TYPE(cp_fm_type), POINTER :: mo_coeff
1689 : TYPE(cp_logger_type), POINTER :: logger
1690 10371 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: ks_rmpv, matrix_s
1691 : TYPE(dbcsr_type), POINTER :: mo_coeff_deriv
1692 : TYPE(dft_control_type), POINTER :: dft_control
1693 10371 : TYPE(mo_set_type), DIMENSION(:), POINTER :: mos
1694 10371 : TYPE(molecule_type), POINTER :: molecule_set(:)
1695 : TYPE(particle_list_type), POINTER :: particles
1696 10371 : TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
1697 : TYPE(pw_env_type), POINTER :: pw_env
1698 10371 : TYPE(pw_pool_p_type), DIMENSION(:), POINTER :: pw_pools
1699 : TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
1700 : TYPE(pw_r3d_rs_type) :: wf_r
1701 10371 : TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: rho_r
1702 : TYPE(qs_energy_type), POINTER :: energy
1703 10371 : TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
1704 : TYPE(qs_rho_type), POINTER :: rho
1705 : TYPE(qs_subsys_type), POINTER :: subsys
1706 : TYPE(scf_control_type), POINTER :: scf_control
1707 : TYPE(section_vals_type), POINTER :: dft_section, input, sprint_section, &
1708 : trexio_section
1709 :
1710 : ! TYPE(kpoint_type), POINTER :: kpoints
1711 :
1712 10371 : CALL timeset(routineN, handle)
1713 :
1714 10371 : NULLIFY (cell, dft_control, pw_env, auxbas_pw_pool, pw_pools, mo_coeff, &
1715 10371 : mo_coeff_deriv, mo_eigenvalues, mos, atomic_kind_set, qs_kind_set, &
1716 10371 : particle_set, rho, ks_rmpv, matrix_s, scf_control, dft_section, &
1717 10371 : molecule_set, input, particles, subsys, rho_r)
1718 :
1719 10371 : logger => cp_get_default_logger()
1720 10371 : output_unit = cp_logger_get_default_io_unit(logger)
1721 :
1722 10371 : CPASSERT(ASSOCIATED(qs_env))
1723 : CALL get_qs_env(qs_env, &
1724 : dft_control=dft_control, &
1725 : molecule_set=molecule_set, &
1726 : atomic_kind_set=atomic_kind_set, &
1727 : particle_set=particle_set, &
1728 : qs_kind_set=qs_kind_set, &
1729 : admm_env=admm_env, &
1730 : scf_control=scf_control, &
1731 : input=input, &
1732 : cell=cell, &
1733 10371 : subsys=subsys)
1734 10371 : CALL qs_subsys_get(subsys, particles=particles)
1735 10371 : CALL get_qs_env(qs_env, rho=rho)
1736 10371 : CALL qs_rho_get(rho, rho_r=rho_r)
1737 :
1738 : ! k points
1739 10371 : CALL get_qs_env(qs_env, do_kpoints=do_kpoints)
1740 :
1741 : ! Write last MO information to output file if requested
1742 10371 : dft_section => section_vals_get_subs_vals(input, "DFT")
1743 10371 : IF (.NOT. qs_env%run_rtp) THEN
1744 10059 : CALL qs_scf_write_mos(qs_env, scf_env, final_mos=.TRUE.)
1745 10059 : trexio_section => section_vals_get_subs_vals(dft_section, "PRINT%TREXIO")
1746 10059 : CALL section_vals_get(trexio_section, explicit=explicit)
1747 10059 : IF (explicit) THEN
1748 8 : CALL write_trexio(qs_env, trexio_section)
1749 : END IF
1750 10059 : IF (.NOT. do_kpoints) THEN
1751 9833 : CALL get_qs_env(qs_env, mos=mos, matrix_ks=ks_rmpv)
1752 9833 : CALL write_dm_binary_restart(mos, dft_section, ks_rmpv)
1753 9833 : sprint_section => section_vals_get_subs_vals(dft_section, "PRINT%MO_MOLDEN")
1754 9833 : CALL write_mos_molden(mos, qs_kind_set, particle_set, sprint_section)
1755 : ! Write Chargemol .wfx
1756 9833 : IF (BTEST(cp_print_key_should_output(logger%iter_info, &
1757 : dft_section, "PRINT%CHARGEMOL"), &
1758 : cp_p_file)) THEN
1759 2 : CALL write_wfx(qs_env, dft_section)
1760 : END IF
1761 : END IF
1762 :
1763 : ! DOS printout after the SCF cycle is completed
1764 10059 : IF (BTEST(cp_print_key_should_output(logger%iter_info, dft_section, "PRINT%DOS") &
1765 : , cp_p_file)) THEN
1766 42 : IF (do_kpoints) THEN
1767 2 : CALL calculate_dos_kp(qs_env, dft_section)
1768 : ELSE
1769 40 : CALL get_qs_env(qs_env, mos=mos)
1770 40 : CALL calculate_dos(mos, dft_section)
1771 : END IF
1772 : END IF
1773 :
1774 : ! Print the projected density of states (pDOS) for each atomic kind
1775 10059 : IF (BTEST(cp_print_key_should_output(logger%iter_info, dft_section, "PRINT%PDOS"), &
1776 : cp_p_file)) THEN
1777 48 : IF (do_kpoints) THEN
1778 0 : CPWARN("Projected density of states (pDOS) is not implemented for k points")
1779 : ELSE
1780 : CALL get_qs_env(qs_env, &
1781 : mos=mos, &
1782 48 : matrix_ks=ks_rmpv)
1783 96 : DO ispin = 1, dft_control%nspins
1784 : ! With ADMM, we have to modify the Kohn-Sham matrix
1785 48 : IF (dft_control%do_admm) THEN
1786 0 : CALL admm_correct_for_eigenvalues(ispin, admm_env, ks_rmpv(ispin)%matrix)
1787 : END IF
1788 48 : IF (PRESENT(scf_env)) THEN
1789 48 : IF (scf_env%method == ot_method_nr) THEN
1790 : CALL get_mo_set(mo_set=mos(ispin), mo_coeff=mo_coeff, &
1791 8 : eigenvalues=mo_eigenvalues)
1792 8 : IF (ASSOCIATED(qs_env%mo_derivs)) THEN
1793 8 : mo_coeff_deriv => qs_env%mo_derivs(ispin)%matrix
1794 : ELSE
1795 0 : mo_coeff_deriv => NULL()
1796 : END IF
1797 : CALL calculate_subspace_eigenvalues(mo_coeff, ks_rmpv(ispin)%matrix, mo_eigenvalues, &
1798 : do_rotation=.TRUE., &
1799 8 : co_rotate_dbcsr=mo_coeff_deriv)
1800 8 : CALL set_mo_occupation(mo_set=mos(ispin))
1801 : END IF
1802 : END IF
1803 48 : IF (dft_control%nspins == 2) THEN
1804 : CALL calculate_projected_dos(mos(ispin), atomic_kind_set, &
1805 0 : qs_kind_set, particle_set, qs_env, dft_section, ispin=ispin)
1806 : ELSE
1807 : CALL calculate_projected_dos(mos(ispin), atomic_kind_set, &
1808 48 : qs_kind_set, particle_set, qs_env, dft_section)
1809 : END IF
1810 : ! With ADMM, we have to undo the modification of the Kohn-Sham matrix
1811 96 : IF (dft_control%do_admm) THEN
1812 0 : CALL admm_uncorrect_for_eigenvalues(ispin, admm_env, ks_rmpv(ispin)%matrix)
1813 : END IF
1814 : END DO
1815 : END IF
1816 : END IF
1817 : END IF
1818 :
1819 : ! Integrated absolute spin density and spin contamination ***
1820 10371 : IF (dft_control%nspins == 2) THEN
1821 1982 : CALL get_qs_env(qs_env, mos=mos)
1822 1982 : CALL get_qs_env(qs_env=qs_env, pw_env=pw_env)
1823 : CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool, &
1824 1982 : pw_pools=pw_pools)
1825 1982 : CALL auxbas_pw_pool%create_pw(wf_r)
1826 1982 : CALL pw_copy(rho_r(1), wf_r)
1827 1982 : CALL pw_axpy(rho_r(2), wf_r, alpha=-1._dp)
1828 1982 : total_spin_dens = pw_integrate_function(wf_r)
1829 1982 : IF (output_unit > 0) WRITE (UNIT=output_unit, FMT='(/,(T3,A,T61,F20.10))') &
1830 1014 : "Integrated spin density: ", total_spin_dens
1831 1982 : total_abs_spin_dens = pw_integrate_function(wf_r, oprt="ABS")
1832 1982 : IF (output_unit > 0) WRITE (UNIT=output_unit, FMT='((T3,A,T61,F20.10))') &
1833 1014 : "Integrated absolute spin density: ", total_abs_spin_dens
1834 1982 : CALL auxbas_pw_pool%give_back_pw(wf_r)
1835 : !
1836 : ! XXX Fix Me XXX
1837 : ! should be extended to the case where added MOs are present
1838 : ! should be extended to the k-point case
1839 : !
1840 1982 : IF (do_kpoints) THEN
1841 30 : CPWARN("Spin contamination estimate not implemented for k-points.")
1842 : ELSE
1843 1952 : all_equal = .TRUE.
1844 5856 : DO ispin = 1, dft_control%nspins
1845 : CALL get_mo_set(mo_set=mos(ispin), &
1846 : occupation_numbers=occupation_numbers, &
1847 : homo=homo, &
1848 : nmo=nmo, &
1849 3904 : maxocc=maxocc)
1850 5856 : IF (nmo > 0) THEN
1851 : all_equal = all_equal .AND. &
1852 : (ALL(occupation_numbers(1:homo) == maxocc) .AND. &
1853 22302 : ALL(occupation_numbers(homo + 1:nmo) == 0.0_dp))
1854 : END IF
1855 : END DO
1856 1952 : IF (.NOT. all_equal) THEN
1857 106 : IF (output_unit > 0) WRITE (UNIT=output_unit, FMT="(T3,A)") &
1858 53 : "WARNING: S**2 computation does not yet treat fractional occupied orbitals"
1859 : ELSE
1860 : CALL get_qs_env(qs_env=qs_env, &
1861 : matrix_s=matrix_s, &
1862 1846 : energy=energy)
1863 : CALL compute_s_square(mos=mos, matrix_s=matrix_s, s_square=s_square, &
1864 1846 : s_square_ideal=s_square_ideal)
1865 1846 : IF (output_unit > 0) WRITE (UNIT=output_unit, FMT='(T3,A,T51,2F15.6)') &
1866 946 : "Ideal and single determinant S**2 : ", s_square_ideal, s_square
1867 1846 : energy%s_square = s_square
1868 : END IF
1869 : END IF
1870 : END IF
1871 :
1872 10371 : CALL timestop(handle)
1873 :
1874 10371 : END SUBROUTINE write_mo_dependent_results
1875 :
1876 : ! **************************************************************************************************
1877 : !> \brief Write QS results always available (if switched on through the print_keys)
1878 : !> Can be called from ls_scf
1879 : !> \param qs_env the qs_env in which the qs_env lives
1880 : ! **************************************************************************************************
1881 11305 : SUBROUTINE write_mo_free_results(qs_env)
1882 : TYPE(qs_environment_type), POINTER :: qs_env
1883 :
1884 : CHARACTER(len=*), PARAMETER :: routineN = 'write_mo_free_results'
1885 : CHARACTER(len=1), DIMENSION(3), PARAMETER :: cdir = ["x", "y", "z"]
1886 :
1887 : CHARACTER(LEN=2) :: element_symbol
1888 : CHARACTER(LEN=default_path_length) :: filename, mpi_filename, my_pos_cube, &
1889 : my_pos_voro
1890 : CHARACTER(LEN=default_string_length) :: name, print_density
1891 : INTEGER :: after, handle, i, iat, iatom, id, ikind, img, iso, ispin, iw, l, n_rep_hf, nat, &
1892 : natom, nd(3), ngto, niso, nkind, np, nr, output_unit, print_level, should_print_bqb, &
1893 : should_print_voro, unit_nr, unit_nr_voro
1894 : LOGICAL :: append_cube, append_voro, do_hfx, do_kpoints, mpi_io, omit_headers, print_it, &
1895 : rho_r_valid, voro_print_txt, write_ks, write_xc, xrd_interface
1896 : REAL(KIND=dp) :: norm_factor, q_max, rho_hard, rho_soft, &
1897 : rho_total, rho_total_rspace, udvol, &
1898 : volume, zeff
1899 11305 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:) :: zcharge
1900 11305 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :) :: bfun
1901 11305 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :) :: aedens, ccdens, ppdens
1902 : REAL(KIND=dp), DIMENSION(3) :: dr
1903 11305 : REAL(KIND=dp), DIMENSION(:), POINTER :: my_Q0
1904 11305 : TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
1905 : TYPE(atomic_kind_type), POINTER :: atomic_kind
1906 : TYPE(cell_type), POINTER :: cell
1907 : TYPE(cp_logger_type), POINTER :: logger
1908 11305 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_hr
1909 11305 : TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: ks_rmpv, matrix_vxc, rho_ao
1910 : TYPE(dft_control_type), POINTER :: dft_control
1911 : TYPE(grid_atom_type), POINTER :: grid_atom
1912 : TYPE(iao_env_type) :: iao_env
1913 : TYPE(mp_para_env_type), POINTER :: para_env
1914 : TYPE(particle_list_type), POINTER :: particles
1915 11305 : TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
1916 : TYPE(pw_c1d_gs_type) :: aux_g, rho_elec_gspace
1917 : TYPE(pw_c1d_gs_type), POINTER :: rho0_s_gs, rho_core, rhoz_cneo_s_gs
1918 : TYPE(pw_env_type), POINTER :: pw_env
1919 11305 : TYPE(pw_pool_p_type), DIMENSION(:), POINTER :: pw_pools
1920 : TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
1921 : TYPE(pw_r3d_rs_type) :: aux_r, rho_elec_rspace, wf_r
1922 11305 : TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: rho_r
1923 : TYPE(pw_r3d_rs_type), POINTER :: mb_rho, v_hartree_rspace, vee
1924 11305 : TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
1925 : TYPE(qs_kind_type), POINTER :: qs_kind
1926 : TYPE(qs_rho_type), POINTER :: rho
1927 : TYPE(qs_subsys_type), POINTER :: subsys
1928 : TYPE(rho0_mpole_type), POINTER :: rho0_mpole
1929 11305 : TYPE(rho_atom_type), DIMENSION(:), POINTER :: rho_atom_set
1930 : TYPE(rho_atom_type), POINTER :: rho_atom
1931 : TYPE(section_vals_type), POINTER :: dft_section, hfx_section, input, &
1932 : print_key, print_key_bqb, &
1933 : print_key_voro, xc_section
1934 :
1935 11305 : CALL timeset(routineN, handle)
1936 11305 : NULLIFY (cell, dft_control, pw_env, auxbas_pw_pool, pw_pools, hfx_section, &
1937 11305 : atomic_kind_set, qs_kind_set, particle_set, rho, ks_rmpv, rho_ao, rho_r, &
1938 11305 : dft_section, xc_section, input, particles, subsys, matrix_vxc, v_hartree_rspace, &
1939 11305 : vee)
1940 :
1941 11305 : logger => cp_get_default_logger()
1942 11305 : output_unit = cp_logger_get_default_io_unit(logger)
1943 :
1944 11305 : CPASSERT(ASSOCIATED(qs_env))
1945 : CALL get_qs_env(qs_env, &
1946 : atomic_kind_set=atomic_kind_set, &
1947 : qs_kind_set=qs_kind_set, &
1948 : particle_set=particle_set, &
1949 : cell=cell, &
1950 : para_env=para_env, &
1951 : dft_control=dft_control, &
1952 : input=input, &
1953 : do_kpoints=do_kpoints, &
1954 11305 : subsys=subsys)
1955 11305 : dft_section => section_vals_get_subs_vals(input, "DFT")
1956 11305 : CALL qs_subsys_get(subsys, particles=particles)
1957 :
1958 11305 : CALL get_qs_env(qs_env, rho=rho)
1959 11305 : CALL qs_rho_get(rho, rho_r=rho_r)
1960 :
1961 11305 : CALL get_qs_env(qs_env, nkind=nkind, natom=natom)
1962 33915 : ALLOCATE (zcharge(natom))
1963 31663 : DO ikind = 1, nkind
1964 20358 : CALL get_qs_kind(qs_kind_set(ikind), zeff=zeff)
1965 20358 : CALL get_atomic_kind(atomic_kind_set(ikind), natom=nat)
1966 74866 : DO iatom = 1, nat
1967 43203 : iat = atomic_kind_set(ikind)%atom_list(iatom)
1968 63561 : zcharge(iat) = zeff
1969 : END DO
1970 : END DO
1971 :
1972 : ! Print the total density (electronic + core charge)
1973 11305 : IF (BTEST(cp_print_key_should_output(logger%iter_info, input, &
1974 : "DFT%PRINT%TOT_DENSITY_CUBE"), cp_p_file)) THEN
1975 82 : NULLIFY (rho_core, rho0_s_gs, rhoz_cneo_s_gs)
1976 82 : append_cube = section_get_lval(input, "DFT%PRINT%TOT_DENSITY_CUBE%APPEND")
1977 82 : my_pos_cube = "REWIND"
1978 82 : IF (append_cube) THEN
1979 0 : my_pos_cube = "APPEND"
1980 : END IF
1981 :
1982 : CALL get_qs_env(qs_env=qs_env, pw_env=pw_env, rho_core=rho_core, &
1983 82 : rho0_s_gs=rho0_s_gs, rhoz_cneo_s_gs=rhoz_cneo_s_gs)
1984 : CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool, &
1985 82 : pw_pools=pw_pools)
1986 82 : CALL auxbas_pw_pool%create_pw(wf_r)
1987 82 : IF (dft_control%qs_control%gapw) THEN
1988 0 : IF (dft_control%qs_control%gapw_control%nopaw_as_gpw) THEN
1989 0 : CALL pw_axpy(rho_core, rho0_s_gs)
1990 0 : IF (ASSOCIATED(rhoz_cneo_s_gs)) THEN
1991 0 : CALL pw_axpy(rhoz_cneo_s_gs, rho0_s_gs)
1992 : END IF
1993 0 : CALL pw_transfer(rho0_s_gs, wf_r)
1994 0 : CALL pw_axpy(rho_core, rho0_s_gs, -1.0_dp)
1995 0 : IF (ASSOCIATED(rhoz_cneo_s_gs)) THEN
1996 0 : CALL pw_axpy(rhoz_cneo_s_gs, rho0_s_gs, -1.0_dp)
1997 : END IF
1998 : ELSE
1999 0 : IF (ASSOCIATED(rhoz_cneo_s_gs)) THEN
2000 0 : CALL pw_axpy(rhoz_cneo_s_gs, rho0_s_gs)
2001 : END IF
2002 0 : CALL pw_transfer(rho0_s_gs, wf_r)
2003 0 : IF (ASSOCIATED(rhoz_cneo_s_gs)) THEN
2004 0 : CALL pw_axpy(rhoz_cneo_s_gs, rho0_s_gs, -1.0_dp)
2005 : END IF
2006 : END IF
2007 : ELSE
2008 82 : CALL pw_transfer(rho_core, wf_r)
2009 : END IF
2010 164 : DO ispin = 1, dft_control%nspins
2011 164 : CALL pw_axpy(rho_r(ispin), wf_r)
2012 : END DO
2013 82 : filename = "TOTAL_DENSITY"
2014 82 : mpi_io = .TRUE.
2015 : unit_nr = cp_print_key_unit_nr(logger, input, "DFT%PRINT%TOT_DENSITY_CUBE", &
2016 : extension=".cube", middle_name=TRIM(filename), file_position=my_pos_cube, &
2017 82 : log_filename=.FALSE., mpi_io=mpi_io)
2018 : CALL cp_pw_to_cube(wf_r, unit_nr, "TOTAL DENSITY", &
2019 : particles=particles, zeff=zcharge, &
2020 82 : stride=section_get_ivals(dft_section, "PRINT%TOT_DENSITY_CUBE%STRIDE"), mpi_io=mpi_io)
2021 : CALL cp_print_key_finished_output(unit_nr, logger, input, &
2022 82 : "DFT%PRINT%TOT_DENSITY_CUBE", mpi_io=mpi_io)
2023 82 : CALL auxbas_pw_pool%give_back_pw(wf_r)
2024 : END IF
2025 :
2026 : ! Write cube file with electron density
2027 11305 : IF (BTEST(cp_print_key_should_output(logger%iter_info, input, &
2028 : "DFT%PRINT%E_DENSITY_CUBE"), cp_p_file)) THEN
2029 : CALL section_vals_val_get(dft_section, &
2030 : keyword_name="PRINT%E_DENSITY_CUBE%DENSITY_INCLUDE", &
2031 150 : c_val=print_density)
2032 : print_density = TRIM(print_density)
2033 150 : append_cube = section_get_lval(input, "DFT%PRINT%E_DENSITY_CUBE%APPEND")
2034 150 : my_pos_cube = "REWIND"
2035 150 : IF (append_cube) THEN
2036 0 : my_pos_cube = "APPEND"
2037 : END IF
2038 : ! Write the info on core densities for the interface between cp2k and the XRD code
2039 : ! together with the valence density they are used to compute the form factor (Fourier transform)
2040 150 : xrd_interface = section_get_lval(input, "DFT%PRINT%E_DENSITY_CUBE%XRD_INTERFACE")
2041 150 : IF (xrd_interface) THEN
2042 : !cube file only contains soft density (GAPW)
2043 2 : IF (dft_control%qs_control%gapw) print_density = "SOFT_DENSITY"
2044 :
2045 2 : filename = "ELECTRON_DENSITY"
2046 : unit_nr = cp_print_key_unit_nr(logger, input, "DFT%PRINT%E_DENSITY_CUBE", &
2047 : extension=".xrd", middle_name=TRIM(filename), &
2048 2 : file_position=my_pos_cube, log_filename=.FALSE.)
2049 2 : ngto = section_get_ival(input, "DFT%PRINT%E_DENSITY_CUBE%NGAUSS")
2050 2 : IF (output_unit > 0) THEN
2051 1 : INQUIRE (UNIT=unit_nr, NAME=filename)
2052 : WRITE (UNIT=output_unit, FMT="(/,T2,A,/,/,T2,A)") &
2053 1 : "The electron density (atomic part) is written to the file:", &
2054 2 : TRIM(filename)
2055 : END IF
2056 :
2057 2 : xc_section => section_vals_get_subs_vals(input, "DFT%XC")
2058 2 : nkind = SIZE(atomic_kind_set)
2059 2 : IF (unit_nr > 0) THEN
2060 1 : WRITE (unit_nr, *) "Atomic (core) densities"
2061 1 : WRITE (unit_nr, *) "Unit cell"
2062 1 : WRITE (unit_nr, FMT="(3F20.12)") cell%hmat(1, 1), cell%hmat(1, 2), cell%hmat(1, 3)
2063 1 : WRITE (unit_nr, FMT="(3F20.12)") cell%hmat(2, 1), cell%hmat(2, 2), cell%hmat(2, 3)
2064 1 : WRITE (unit_nr, FMT="(3F20.12)") cell%hmat(3, 1), cell%hmat(3, 2), cell%hmat(3, 3)
2065 1 : WRITE (unit_nr, *) "Atomic types"
2066 1 : WRITE (unit_nr, *) nkind
2067 : END IF
2068 : ! calculate atomic density and core density
2069 16 : ALLOCATE (ppdens(ngto, 2, nkind), aedens(ngto, 2, nkind), ccdens(ngto, 2, nkind))
2070 6 : DO ikind = 1, nkind
2071 4 : atomic_kind => atomic_kind_set(ikind)
2072 4 : qs_kind => qs_kind_set(ikind)
2073 4 : CALL get_atomic_kind(atomic_kind, name=name, element_symbol=element_symbol)
2074 : CALL calculate_atomic_density(ppdens(:, :, ikind), atomic_kind, qs_kind, ngto, &
2075 4 : iunit=output_unit, confine=.TRUE.)
2076 : CALL calculate_atomic_density(aedens(:, :, ikind), atomic_kind, qs_kind, ngto, &
2077 4 : iunit=output_unit, allelectron=.TRUE., confine=.TRUE.)
2078 52 : ccdens(:, 1, ikind) = aedens(:, 1, ikind)
2079 52 : ccdens(:, 2, ikind) = 0._dp
2080 : CALL project_function_a(ccdens(1:ngto, 2, ikind), ccdens(1:ngto, 1, ikind), &
2081 4 : ppdens(1:ngto, 2, ikind), ppdens(1:ngto, 1, ikind), 0)
2082 52 : ccdens(:, 2, ikind) = aedens(:, 2, ikind) - ccdens(:, 2, ikind)
2083 4 : IF (unit_nr > 0) THEN
2084 2 : WRITE (unit_nr, FMT="(I6,A10,A20)") ikind, TRIM(element_symbol), TRIM(name)
2085 2 : WRITE (unit_nr, FMT="(I6)") ngto
2086 2 : WRITE (unit_nr, *) " Total density"
2087 26 : WRITE (unit_nr, FMT="(2G24.12)") (aedens(i, 1, ikind), aedens(i, 2, ikind), i=1, ngto)
2088 2 : WRITE (unit_nr, *) " Core density"
2089 26 : WRITE (unit_nr, FMT="(2G24.12)") (ccdens(i, 1, ikind), ccdens(i, 2, ikind), i=1, ngto)
2090 : END IF
2091 6 : NULLIFY (atomic_kind)
2092 : END DO
2093 :
2094 2 : IF (dft_control%qs_control%gapw) THEN
2095 2 : CALL get_qs_env(qs_env=qs_env, rho_atom_set=rho_atom_set)
2096 :
2097 2 : IF (unit_nr > 0) THEN
2098 1 : WRITE (unit_nr, *) "Coordinates and GAPW density"
2099 : END IF
2100 2 : np = particles%n_els
2101 6 : DO iat = 1, np
2102 4 : CALL get_atomic_kind(particles%els(iat)%atomic_kind, kind_number=ikind)
2103 4 : CALL get_qs_kind(qs_kind_set(ikind), grid_atom=grid_atom)
2104 4 : rho_atom => rho_atom_set(iat)
2105 4 : IF (ASSOCIATED(rho_atom%rho_rad_h(1)%r_coef)) THEN
2106 2 : nr = SIZE(rho_atom%rho_rad_h(1)%r_coef, 1)
2107 2 : niso = SIZE(rho_atom%rho_rad_h(1)%r_coef, 2)
2108 : ELSE
2109 2 : nr = 0
2110 2 : niso = 0
2111 : END IF
2112 4 : CALL para_env%sum(nr)
2113 4 : CALL para_env%sum(niso)
2114 :
2115 16 : ALLOCATE (bfun(nr, niso))
2116 1840 : bfun = 0._dp
2117 8 : DO ispin = 1, dft_control%nspins
2118 8 : IF (ASSOCIATED(rho_atom%rho_rad_h(1)%r_coef)) THEN
2119 920 : bfun(:, :) = bfun + rho_atom%rho_rad_h(ispin)%r_coef - rho_atom%rho_rad_s(ispin)%r_coef
2120 : END IF
2121 : END DO
2122 4 : CALL para_env%sum(bfun)
2123 52 : ccdens(:, 1, ikind) = ppdens(:, 1, ikind)
2124 52 : ccdens(:, 2, ikind) = 0._dp
2125 4 : IF (unit_nr > 0) THEN
2126 8 : WRITE (unit_nr, '(I10,I5,3f12.6)') iat, ikind, particles%els(iat)%r
2127 : END IF
2128 40 : DO iso = 1, niso
2129 36 : l = indso(1, iso)
2130 36 : CALL project_function_b(ccdens(:, 2, ikind), ccdens(:, 1, ikind), bfun(:, iso), grid_atom, l)
2131 40 : IF (unit_nr > 0) THEN
2132 18 : WRITE (unit_nr, FMT="(3I6)") iso, l, ngto
2133 234 : WRITE (unit_nr, FMT="(2G24.12)") (ccdens(i, 1, ikind), ccdens(i, 2, ikind), i=1, ngto)
2134 : END IF
2135 : END DO
2136 10 : DEALLOCATE (bfun)
2137 : END DO
2138 : ELSE
2139 0 : IF (unit_nr > 0) THEN
2140 0 : WRITE (unit_nr, *) "Coordinates"
2141 0 : np = particles%n_els
2142 0 : DO iat = 1, np
2143 0 : CALL get_atomic_kind(particles%els(iat)%atomic_kind, kind_number=ikind)
2144 0 : WRITE (unit_nr, '(I10,I5,3f12.6)') iat, ikind, particles%els(iat)%r
2145 : END DO
2146 : END IF
2147 : END IF
2148 :
2149 2 : DEALLOCATE (ppdens, aedens, ccdens)
2150 :
2151 : CALL cp_print_key_finished_output(unit_nr, logger, input, &
2152 2 : "DFT%PRINT%E_DENSITY_CUBE")
2153 :
2154 : END IF
2155 150 : IF (dft_control%qs_control%gapw .AND. print_density == "TOTAL_DENSITY") THEN
2156 : ! total density in g-space not implemented for k-points
2157 4 : CPASSERT(.NOT. do_kpoints)
2158 : ! Print total electronic density
2159 : CALL get_qs_env(qs_env=qs_env, &
2160 4 : pw_env=pw_env)
2161 : CALL pw_env_get(pw_env=pw_env, &
2162 : auxbas_pw_pool=auxbas_pw_pool, &
2163 4 : pw_pools=pw_pools)
2164 4 : CALL auxbas_pw_pool%create_pw(pw=rho_elec_rspace)
2165 4 : CALL pw_zero(rho_elec_rspace)
2166 4 : CALL auxbas_pw_pool%create_pw(pw=rho_elec_gspace)
2167 4 : CALL pw_zero(rho_elec_gspace)
2168 : CALL get_pw_grid_info(pw_grid=rho_elec_gspace%pw_grid, &
2169 : dr=dr, &
2170 4 : vol=volume)
2171 16 : q_max = SQRT(SUM((pi/dr(:))**2))
2172 : CALL calculate_rhotot_elec_gspace(qs_env=qs_env, &
2173 : auxbas_pw_pool=auxbas_pw_pool, &
2174 : rhotot_elec_gspace=rho_elec_gspace, &
2175 : q_max=q_max, &
2176 : rho_hard=rho_hard, &
2177 4 : rho_soft=rho_soft)
2178 4 : rho_total = rho_hard + rho_soft
2179 : CALL get_pw_grid_info(pw_grid=rho_elec_gspace%pw_grid, &
2180 4 : vol=volume)
2181 : ! rhotot pw coefficients are by default scaled by grid volume
2182 : ! need to undo this to get proper charge from printed cube
2183 4 : CALL pw_scale(rho_elec_gspace, 1.0_dp/volume)
2184 :
2185 4 : CALL pw_transfer(rho_elec_gspace, rho_elec_rspace)
2186 4 : rho_total_rspace = pw_integrate_function(rho_elec_rspace, isign=-1)
2187 4 : filename = "TOTAL_ELECTRON_DENSITY"
2188 4 : mpi_io = .TRUE.
2189 : unit_nr = cp_print_key_unit_nr(logger, input, "DFT%PRINT%E_DENSITY_CUBE", &
2190 : extension=".cube", middle_name=TRIM(filename), &
2191 : file_position=my_pos_cube, log_filename=.FALSE., mpi_io=mpi_io, &
2192 4 : fout=mpi_filename)
2193 4 : IF (output_unit > 0) THEN
2194 2 : IF (.NOT. mpi_io) THEN
2195 0 : INQUIRE (UNIT=unit_nr, NAME=filename)
2196 : ELSE
2197 2 : filename = mpi_filename
2198 : END IF
2199 : WRITE (UNIT=output_unit, FMT="(/,T2,A,/,/,T2,A)") &
2200 2 : "The total electron density is written in cube file format to the file:", &
2201 4 : TRIM(filename)
2202 : WRITE (UNIT=output_unit, FMT="(/,(T2,A,F20.10))") &
2203 2 : "q(max) [1/Angstrom] :", q_max/angstrom, &
2204 2 : "Soft electronic charge (G-space) :", rho_soft, &
2205 2 : "Hard electronic charge (G-space) :", rho_hard, &
2206 2 : "Total electronic charge (G-space):", rho_total, &
2207 4 : "Total electronic charge (R-space):", rho_total_rspace
2208 : END IF
2209 : CALL cp_pw_to_cube(rho_elec_rspace, unit_nr, "TOTAL ELECTRON DENSITY", &
2210 : particles=particles, zeff=zcharge, &
2211 4 : stride=section_get_ivals(dft_section, "PRINT%E_DENSITY_CUBE%STRIDE"), mpi_io=mpi_io)
2212 : CALL cp_print_key_finished_output(unit_nr, logger, input, &
2213 4 : "DFT%PRINT%E_DENSITY_CUBE", mpi_io=mpi_io)
2214 : ! Print total spin density for spin-polarized systems
2215 4 : IF (dft_control%nspins > 1) THEN
2216 2 : CALL pw_zero(rho_elec_gspace)
2217 2 : CALL pw_zero(rho_elec_rspace)
2218 : CALL calculate_rhotot_elec_gspace(qs_env=qs_env, &
2219 : auxbas_pw_pool=auxbas_pw_pool, &
2220 : rhotot_elec_gspace=rho_elec_gspace, &
2221 : q_max=q_max, &
2222 : rho_hard=rho_hard, &
2223 : rho_soft=rho_soft, &
2224 2 : fsign=-1.0_dp)
2225 2 : rho_total = rho_hard + rho_soft
2226 :
2227 : ! rhotot pw coefficients are by default scaled by grid volume
2228 : ! need to undo this to get proper charge from printed cube
2229 2 : CALL pw_scale(rho_elec_gspace, 1.0_dp/volume)
2230 :
2231 2 : CALL pw_transfer(rho_elec_gspace, rho_elec_rspace)
2232 2 : rho_total_rspace = pw_integrate_function(rho_elec_rspace, isign=-1)
2233 2 : filename = "TOTAL_SPIN_DENSITY"
2234 2 : mpi_io = .TRUE.
2235 : unit_nr = cp_print_key_unit_nr(logger, input, "DFT%PRINT%E_DENSITY_CUBE", &
2236 : extension=".cube", middle_name=TRIM(filename), &
2237 : file_position=my_pos_cube, log_filename=.FALSE., mpi_io=mpi_io, &
2238 2 : fout=mpi_filename)
2239 2 : IF (output_unit > 0) THEN
2240 1 : IF (.NOT. mpi_io) THEN
2241 0 : INQUIRE (UNIT=unit_nr, NAME=filename)
2242 : ELSE
2243 1 : filename = mpi_filename
2244 : END IF
2245 : WRITE (UNIT=output_unit, FMT="(/,T2,A,/,/,T2,A)") &
2246 1 : "The total spin density is written in cube file format to the file:", &
2247 2 : TRIM(filename)
2248 : WRITE (UNIT=output_unit, FMT="(/,(T2,A,F20.10))") &
2249 1 : "q(max) [1/Angstrom] :", q_max/angstrom, &
2250 1 : "Soft part of the spin density (G-space):", rho_soft, &
2251 1 : "Hard part of the spin density (G-space):", rho_hard, &
2252 1 : "Total spin density (G-space) :", rho_total, &
2253 2 : "Total spin density (R-space) :", rho_total_rspace
2254 : END IF
2255 : CALL cp_pw_to_cube(rho_elec_rspace, unit_nr, "TOTAL SPIN DENSITY", &
2256 : particles=particles, zeff=zcharge, &
2257 2 : stride=section_get_ivals(dft_section, "PRINT%E_DENSITY_CUBE%STRIDE"), mpi_io=mpi_io)
2258 : CALL cp_print_key_finished_output(unit_nr, logger, input, &
2259 2 : "DFT%PRINT%E_DENSITY_CUBE", mpi_io=mpi_io)
2260 : END IF
2261 4 : CALL auxbas_pw_pool%give_back_pw(rho_elec_gspace)
2262 4 : CALL auxbas_pw_pool%give_back_pw(rho_elec_rspace)
2263 :
2264 146 : ELSE IF (print_density == "SOFT_DENSITY" .OR. .NOT. dft_control%qs_control%gapw) THEN
2265 142 : IF (dft_control%nspins > 1) THEN
2266 : CALL get_qs_env(qs_env=qs_env, &
2267 48 : pw_env=pw_env)
2268 : CALL pw_env_get(pw_env=pw_env, &
2269 : auxbas_pw_pool=auxbas_pw_pool, &
2270 48 : pw_pools=pw_pools)
2271 48 : CALL auxbas_pw_pool%create_pw(pw=rho_elec_rspace)
2272 48 : CALL pw_copy(rho_r(1), rho_elec_rspace)
2273 48 : CALL pw_axpy(rho_r(2), rho_elec_rspace)
2274 48 : filename = "ELECTRON_DENSITY"
2275 48 : mpi_io = .TRUE.
2276 : unit_nr = cp_print_key_unit_nr(logger, input, "DFT%PRINT%E_DENSITY_CUBE", &
2277 : extension=".cube", middle_name=TRIM(filename), &
2278 : file_position=my_pos_cube, log_filename=.FALSE., mpi_io=mpi_io, &
2279 48 : fout=mpi_filename)
2280 48 : IF (output_unit > 0) THEN
2281 24 : IF (.NOT. mpi_io) THEN
2282 0 : INQUIRE (UNIT=unit_nr, NAME=filename)
2283 : ELSE
2284 24 : filename = mpi_filename
2285 : END IF
2286 : WRITE (UNIT=output_unit, FMT="(/,T2,A,/,/,T2,A)") &
2287 24 : "The sum of alpha and beta density is written in cube file format to the file:", &
2288 48 : TRIM(filename)
2289 : END IF
2290 : CALL cp_pw_to_cube(rho_elec_rspace, unit_nr, "SUM OF ALPHA AND BETA DENSITY", &
2291 : particles=particles, zeff=zcharge, &
2292 : stride=section_get_ivals(dft_section, "PRINT%E_DENSITY_CUBE%STRIDE"), &
2293 48 : mpi_io=mpi_io)
2294 : CALL cp_print_key_finished_output(unit_nr, logger, input, &
2295 48 : "DFT%PRINT%E_DENSITY_CUBE", mpi_io=mpi_io)
2296 48 : CALL pw_copy(rho_r(1), rho_elec_rspace)
2297 48 : CALL pw_axpy(rho_r(2), rho_elec_rspace, alpha=-1.0_dp)
2298 48 : filename = "SPIN_DENSITY"
2299 48 : mpi_io = .TRUE.
2300 : unit_nr = cp_print_key_unit_nr(logger, input, "DFT%PRINT%E_DENSITY_CUBE", &
2301 : extension=".cube", middle_name=TRIM(filename), &
2302 : file_position=my_pos_cube, log_filename=.FALSE., mpi_io=mpi_io, &
2303 48 : fout=mpi_filename)
2304 48 : IF (output_unit > 0) THEN
2305 24 : IF (.NOT. mpi_io) THEN
2306 0 : INQUIRE (UNIT=unit_nr, NAME=filename)
2307 : ELSE
2308 24 : filename = mpi_filename
2309 : END IF
2310 : WRITE (UNIT=output_unit, FMT="(/,T2,A,/,/,T2,A)") &
2311 24 : "The spin density is written in cube file format to the file:", &
2312 48 : TRIM(filename)
2313 : END IF
2314 : CALL cp_pw_to_cube(rho_elec_rspace, unit_nr, "SPIN DENSITY", &
2315 : particles=particles, zeff=zcharge, &
2316 48 : stride=section_get_ivals(dft_section, "PRINT%E_DENSITY_CUBE%STRIDE"), mpi_io=mpi_io)
2317 : CALL cp_print_key_finished_output(unit_nr, logger, input, &
2318 48 : "DFT%PRINT%E_DENSITY_CUBE", mpi_io=mpi_io)
2319 48 : CALL auxbas_pw_pool%give_back_pw(rho_elec_rspace)
2320 : ELSE
2321 94 : filename = "ELECTRON_DENSITY"
2322 94 : mpi_io = .TRUE.
2323 : unit_nr = cp_print_key_unit_nr(logger, input, "DFT%PRINT%E_DENSITY_CUBE", &
2324 : extension=".cube", middle_name=TRIM(filename), &
2325 : file_position=my_pos_cube, log_filename=.FALSE., mpi_io=mpi_io, &
2326 94 : fout=mpi_filename)
2327 94 : IF (output_unit > 0) THEN
2328 47 : IF (.NOT. mpi_io) THEN
2329 0 : INQUIRE (UNIT=unit_nr, NAME=filename)
2330 : ELSE
2331 47 : filename = mpi_filename
2332 : END IF
2333 : WRITE (UNIT=output_unit, FMT="(/,T2,A,/,/,T2,A)") &
2334 47 : "The electron density is written in cube file format to the file:", &
2335 94 : TRIM(filename)
2336 : END IF
2337 : CALL cp_pw_to_cube(rho_r(1), unit_nr, "ELECTRON DENSITY", &
2338 : particles=particles, zeff=zcharge, &
2339 94 : stride=section_get_ivals(dft_section, "PRINT%E_DENSITY_CUBE%STRIDE"), mpi_io=mpi_io)
2340 : CALL cp_print_key_finished_output(unit_nr, logger, input, &
2341 94 : "DFT%PRINT%E_DENSITY_CUBE", mpi_io=mpi_io)
2342 : END IF ! nspins
2343 :
2344 4 : ELSE IF (dft_control%qs_control%gapw .AND. print_density == "TOTAL_HARD_APPROX") THEN
2345 4 : CALL get_qs_env(qs_env=qs_env, pw_env=pw_env, rho0_mpole=rho0_mpole, natom=natom)
2346 4 : CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool, pw_pools=pw_pools)
2347 4 : CALL auxbas_pw_pool%create_pw(rho_elec_rspace)
2348 :
2349 4 : NULLIFY (my_Q0)
2350 12 : ALLOCATE (my_Q0(natom))
2351 16 : my_Q0 = 0.0_dp
2352 :
2353 : ! (eta/pi)**3: normalization for 3d gaussian of form exp(-eta*r**2)
2354 4 : norm_factor = SQRT((rho0_mpole%zet0_h/pi)**3)
2355 :
2356 : ! store hard part of electronic density in array
2357 16 : DO iat = 1, natom
2358 34 : my_Q0(iat) = SUM(rho0_mpole%mp_rho(iat)%Q0(1:dft_control%nspins))*norm_factor
2359 : END DO
2360 : ! multiply coeff with gaussian and put on realspace grid
2361 : ! coeff is the gaussian prefactor, eta the gaussian exponent
2362 4 : CALL calculate_rho_resp_all(rho_elec_rspace, coeff=my_Q0, natom=natom, eta=rho0_mpole%zet0_h, qs_env=qs_env)
2363 4 : rho_hard = pw_integrate_function(rho_elec_rspace, isign=-1)
2364 :
2365 4 : rho_soft = 0.0_dp
2366 10 : DO ispin = 1, dft_control%nspins
2367 6 : CALL pw_axpy(rho_r(ispin), rho_elec_rspace)
2368 10 : rho_soft = rho_soft + pw_integrate_function(rho_r(ispin), isign=-1)
2369 : END DO
2370 :
2371 4 : rho_total_rspace = rho_soft + rho_hard
2372 :
2373 4 : filename = "ELECTRON_DENSITY"
2374 4 : mpi_io = .TRUE.
2375 : unit_nr = cp_print_key_unit_nr(logger, input, "DFT%PRINT%E_DENSITY_CUBE", &
2376 : extension=".cube", middle_name=TRIM(filename), &
2377 : file_position=my_pos_cube, log_filename=.FALSE., mpi_io=mpi_io, &
2378 4 : fout=mpi_filename)
2379 4 : IF (output_unit > 0) THEN
2380 2 : IF (.NOT. mpi_io) THEN
2381 0 : INQUIRE (UNIT=unit_nr, NAME=filename)
2382 : ELSE
2383 2 : filename = mpi_filename
2384 : END IF
2385 : WRITE (UNIT=output_unit, FMT="(/,T2,A,/,/,T2,A)") &
2386 2 : "The electron density is written in cube file format to the file:", &
2387 4 : TRIM(filename)
2388 : WRITE (UNIT=output_unit, FMT="(/,(T2,A,F20.10))") &
2389 2 : "Soft electronic charge (R-space) :", rho_soft, &
2390 2 : "Hard electronic charge (R-space) :", rho_hard, &
2391 4 : "Total electronic charge (R-space):", rho_total_rspace
2392 : END IF
2393 : CALL cp_pw_to_cube(rho_elec_rspace, unit_nr, "ELECTRON DENSITY", &
2394 : particles=particles, zeff=zcharge, &
2395 : stride=section_get_ivals(dft_section, "PRINT%E_DENSITY_CUBE%STRIDE"), &
2396 4 : mpi_io=mpi_io)
2397 : CALL cp_print_key_finished_output(unit_nr, logger, input, &
2398 4 : "DFT%PRINT%E_DENSITY_CUBE", mpi_io=mpi_io)
2399 :
2400 : !------------
2401 4 : IF (dft_control%nspins > 1) THEN
2402 8 : DO iat = 1, natom
2403 8 : my_Q0(iat) = (rho0_mpole%mp_rho(iat)%Q0(1) - rho0_mpole%mp_rho(iat)%Q0(2))*norm_factor
2404 : END DO
2405 2 : CALL pw_zero(rho_elec_rspace)
2406 2 : CALL calculate_rho_resp_all(rho_elec_rspace, coeff=my_Q0, natom=natom, eta=rho0_mpole%zet0_h, qs_env=qs_env)
2407 2 : rho_hard = pw_integrate_function(rho_elec_rspace, isign=-1)
2408 :
2409 2 : CALL pw_axpy(rho_r(1), rho_elec_rspace)
2410 2 : CALL pw_axpy(rho_r(2), rho_elec_rspace, alpha=-1.0_dp)
2411 : rho_soft = pw_integrate_function(rho_r(1), isign=-1) &
2412 2 : - pw_integrate_function(rho_r(2), isign=-1)
2413 :
2414 2 : rho_total_rspace = rho_soft + rho_hard
2415 :
2416 2 : filename = "SPIN_DENSITY"
2417 2 : mpi_io = .TRUE.
2418 : unit_nr = cp_print_key_unit_nr(logger, input, "DFT%PRINT%E_DENSITY_CUBE", &
2419 : extension=".cube", middle_name=TRIM(filename), &
2420 : file_position=my_pos_cube, log_filename=.FALSE., mpi_io=mpi_io, &
2421 2 : fout=mpi_filename)
2422 2 : IF (output_unit > 0) THEN
2423 1 : IF (.NOT. mpi_io) THEN
2424 0 : INQUIRE (UNIT=unit_nr, NAME=filename)
2425 : ELSE
2426 1 : filename = mpi_filename
2427 : END IF
2428 : WRITE (UNIT=output_unit, FMT="(/,T2,A,/,/,T2,A)") &
2429 1 : "The spin density is written in cube file format to the file:", &
2430 2 : TRIM(filename)
2431 : WRITE (UNIT=output_unit, FMT="(/,(T2,A,F20.10))") &
2432 1 : "Soft part of the spin density :", rho_soft, &
2433 1 : "Hard part of the spin density :", rho_hard, &
2434 2 : "Total spin density (R-space) :", rho_total_rspace
2435 : END IF
2436 : CALL cp_pw_to_cube(rho_elec_rspace, unit_nr, "SPIN DENSITY", &
2437 : particles=particles, zeff=zcharge, &
2438 2 : stride=section_get_ivals(dft_section, "PRINT%E_DENSITY_CUBE%STRIDE"), mpi_io=mpi_io)
2439 : CALL cp_print_key_finished_output(unit_nr, logger, input, &
2440 2 : "DFT%PRINT%E_DENSITY_CUBE", mpi_io=mpi_io)
2441 : END IF ! nspins
2442 4 : CALL auxbas_pw_pool%give_back_pw(rho_elec_rspace)
2443 4 : DEALLOCATE (my_Q0)
2444 : END IF ! print_density
2445 : END IF ! print key
2446 :
2447 : IF (BTEST(cp_print_key_should_output(logger%iter_info, &
2448 11305 : dft_section, "PRINT%ENERGY_WINDOWS"), cp_p_file) .AND. .NOT. do_kpoints) THEN
2449 90 : CALL energy_windows(qs_env)
2450 : END IF
2451 :
2452 : ! Print the hartree potential
2453 11305 : IF (BTEST(cp_print_key_should_output(logger%iter_info, input, &
2454 : "DFT%PRINT%V_HARTREE_CUBE"), cp_p_file)) THEN
2455 :
2456 : CALL get_qs_env(qs_env=qs_env, &
2457 : pw_env=pw_env, &
2458 114 : v_hartree_rspace=v_hartree_rspace)
2459 114 : CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool)
2460 114 : CALL auxbas_pw_pool%create_pw(aux_r)
2461 :
2462 114 : append_cube = section_get_lval(input, "DFT%PRINT%V_HARTREE_CUBE%APPEND")
2463 114 : my_pos_cube = "REWIND"
2464 114 : IF (append_cube) THEN
2465 0 : my_pos_cube = "APPEND"
2466 : END IF
2467 114 : mpi_io = .TRUE.
2468 114 : CALL get_qs_env(qs_env=qs_env, pw_env=pw_env)
2469 114 : CALL pw_env_get(pw_env)
2470 : unit_nr = cp_print_key_unit_nr(logger, input, "DFT%PRINT%V_HARTREE_CUBE", &
2471 114 : extension=".cube", middle_name="v_hartree", file_position=my_pos_cube, mpi_io=mpi_io)
2472 114 : udvol = 1.0_dp/v_hartree_rspace%pw_grid%dvol
2473 :
2474 114 : CALL pw_copy(v_hartree_rspace, aux_r)
2475 114 : CALL pw_scale(aux_r, udvol)
2476 :
2477 : CALL cp_pw_to_cube(aux_r, unit_nr, "HARTREE POTENTIAL", particles=particles, zeff=zcharge, &
2478 : stride=section_get_ivals(dft_section, &
2479 114 : "PRINT%V_HARTREE_CUBE%STRIDE"), mpi_io=mpi_io)
2480 : CALL cp_print_key_finished_output(unit_nr, logger, input, &
2481 114 : "DFT%PRINT%V_HARTREE_CUBE", mpi_io=mpi_io)
2482 :
2483 114 : CALL auxbas_pw_pool%give_back_pw(aux_r)
2484 : END IF
2485 :
2486 : ! Print the external potential
2487 11305 : IF (BTEST(cp_print_key_should_output(logger%iter_info, input, &
2488 : "DFT%PRINT%EXTERNAL_POTENTIAL_CUBE"), cp_p_file)) THEN
2489 86 : IF (dft_control%apply_external_potential) THEN
2490 4 : CALL get_qs_env(qs_env=qs_env, pw_env=pw_env, vee=vee)
2491 4 : CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool)
2492 4 : CALL auxbas_pw_pool%create_pw(aux_r)
2493 :
2494 4 : append_cube = section_get_lval(input, "DFT%PRINT%EXTERNAL_POTENTIAL_CUBE%APPEND")
2495 4 : my_pos_cube = "REWIND"
2496 4 : IF (append_cube) THEN
2497 0 : my_pos_cube = "APPEND"
2498 : END IF
2499 4 : mpi_io = .TRUE.
2500 4 : CALL pw_env_get(pw_env)
2501 : unit_nr = cp_print_key_unit_nr(logger, input, "DFT%PRINT%EXTERNAL_POTENTIAL_CUBE", &
2502 4 : extension=".cube", middle_name="ext_pot", file_position=my_pos_cube, mpi_io=mpi_io)
2503 :
2504 4 : CALL pw_copy(vee, aux_r)
2505 :
2506 : CALL cp_pw_to_cube(aux_r, unit_nr, "EXTERNAL POTENTIAL", particles=particles, zeff=zcharge, &
2507 : stride=section_get_ivals(dft_section, &
2508 4 : "PRINT%EXTERNAL_POTENTIAL_CUBE%STRIDE"), mpi_io=mpi_io)
2509 : CALL cp_print_key_finished_output(unit_nr, logger, input, &
2510 4 : "DFT%PRINT%EXTERNAL_POTENTIAL_CUBE", mpi_io=mpi_io)
2511 :
2512 4 : CALL auxbas_pw_pool%give_back_pw(aux_r)
2513 : END IF
2514 : END IF
2515 :
2516 : ! Print the Electrical Field Components
2517 11305 : IF (BTEST(cp_print_key_should_output(logger%iter_info, input, &
2518 : "DFT%PRINT%EFIELD_CUBE"), cp_p_file)) THEN
2519 :
2520 82 : CALL get_qs_env(qs_env=qs_env, pw_env=pw_env)
2521 82 : CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool)
2522 82 : CALL auxbas_pw_pool%create_pw(aux_r)
2523 82 : CALL auxbas_pw_pool%create_pw(aux_g)
2524 :
2525 82 : append_cube = section_get_lval(input, "DFT%PRINT%EFIELD_CUBE%APPEND")
2526 82 : my_pos_cube = "REWIND"
2527 82 : IF (append_cube) THEN
2528 0 : my_pos_cube = "APPEND"
2529 : END IF
2530 : CALL get_qs_env(qs_env=qs_env, pw_env=pw_env, &
2531 82 : v_hartree_rspace=v_hartree_rspace)
2532 82 : CALL pw_env_get(pw_env)
2533 82 : udvol = 1.0_dp/v_hartree_rspace%pw_grid%dvol
2534 328 : DO id = 1, 3
2535 246 : mpi_io = .TRUE.
2536 : unit_nr = cp_print_key_unit_nr(logger, input, "DFT%PRINT%EFIELD_CUBE", &
2537 : extension=".cube", middle_name="efield_"//cdir(id), file_position=my_pos_cube, &
2538 246 : mpi_io=mpi_io)
2539 :
2540 246 : CALL pw_transfer(v_hartree_rspace, aux_g)
2541 246 : nd = 0
2542 246 : nd(id) = 1
2543 246 : CALL pw_derive(aux_g, nd)
2544 246 : CALL pw_transfer(aux_g, aux_r)
2545 246 : CALL pw_scale(aux_r, udvol)
2546 :
2547 : CALL cp_pw_to_cube(aux_r, &
2548 : unit_nr, "ELECTRIC FIELD", particles=particles, zeff=zcharge, &
2549 : stride=section_get_ivals(dft_section, &
2550 246 : "PRINT%EFIELD_CUBE%STRIDE"), mpi_io=mpi_io)
2551 : CALL cp_print_key_finished_output(unit_nr, logger, input, &
2552 328 : "DFT%PRINT%EFIELD_CUBE", mpi_io=mpi_io)
2553 : END DO
2554 :
2555 82 : CALL auxbas_pw_pool%give_back_pw(aux_r)
2556 82 : CALL auxbas_pw_pool%give_back_pw(aux_g)
2557 : END IF
2558 :
2559 : ! Write cube files from the local energy
2560 11305 : CALL qs_scf_post_local_energy(input, logger, qs_env)
2561 :
2562 : ! Write cube files from the local stress tensor
2563 11305 : CALL qs_scf_post_local_stress(input, logger, qs_env)
2564 :
2565 : ! Write cube files from the implicit Poisson solver
2566 11305 : CALL qs_scf_post_ps_implicit(input, logger, qs_env)
2567 :
2568 : ! post SCF Transport
2569 11305 : CALL qs_scf_post_transport(qs_env)
2570 :
2571 11305 : CALL section_vals_val_get(input, "DFT%PRINT%AO_MATRICES%OMIT_HEADERS", l_val=omit_headers)
2572 : ! Write the density matrices
2573 11305 : IF (BTEST(cp_print_key_should_output(logger%iter_info, input, &
2574 : "DFT%PRINT%AO_MATRICES/DENSITY"), cp_p_file)) THEN
2575 : iw = cp_print_key_unit_nr(logger, input, "DFT%PRINT%AO_MATRICES/DENSITY", &
2576 4 : extension=".Log")
2577 4 : CALL section_vals_val_get(input, "DFT%PRINT%AO_MATRICES%NDIGITS", i_val=after)
2578 4 : CALL qs_rho_get(rho, rho_ao_kp=rho_ao)
2579 4 : after = MIN(MAX(after, 1), 16)
2580 8 : DO ispin = 1, dft_control%nspins
2581 12 : DO img = 1, dft_control%nimages
2582 : CALL cp_dbcsr_write_sparse_matrix(rho_ao(ispin, img)%matrix, 4, after, qs_env, &
2583 8 : para_env, output_unit=iw, omit_headers=omit_headers)
2584 : END DO
2585 : END DO
2586 : CALL cp_print_key_finished_output(iw, logger, input, &
2587 4 : "DFT%PRINT%AO_MATRICES/DENSITY")
2588 : END IF
2589 :
2590 : ! Write the Kohn-Sham matrices
2591 : write_ks = BTEST(cp_print_key_should_output(logger%iter_info, input, &
2592 11305 : "DFT%PRINT%AO_MATRICES/KOHN_SHAM_MATRIX"), cp_p_file)
2593 : write_xc = BTEST(cp_print_key_should_output(logger%iter_info, input, &
2594 11305 : "DFT%PRINT%AO_MATRICES/MATRIX_VXC"), cp_p_file)
2595 : ! we need to update stuff before writing, potentially computing the matrix_vxc
2596 11305 : IF (write_ks .OR. write_xc) THEN
2597 4 : IF (write_xc) qs_env%requires_matrix_vxc = .TRUE.
2598 4 : CALL qs_ks_did_change(qs_env%ks_env, rho_changed=.TRUE.)
2599 : CALL qs_ks_update_qs_env(qs_env, calculate_forces=.FALSE., &
2600 4 : just_energy=.FALSE.)
2601 4 : IF (write_xc) qs_env%requires_matrix_vxc = .FALSE.
2602 : END IF
2603 :
2604 : ! Write the Kohn-Sham matrices
2605 11305 : IF (write_ks) THEN
2606 : iw = cp_print_key_unit_nr(logger, input, "DFT%PRINT%AO_MATRICES/KOHN_SHAM_MATRIX", &
2607 4 : extension=".Log")
2608 4 : CALL get_qs_env(qs_env=qs_env, matrix_ks_kp=ks_rmpv)
2609 4 : CALL section_vals_val_get(input, "DFT%PRINT%AO_MATRICES%NDIGITS", i_val=after)
2610 4 : after = MIN(MAX(after, 1), 16)
2611 8 : DO ispin = 1, dft_control%nspins
2612 12 : DO img = 1, dft_control%nimages
2613 : CALL cp_dbcsr_write_sparse_matrix(ks_rmpv(ispin, img)%matrix, 4, after, qs_env, &
2614 8 : para_env, output_unit=iw, omit_headers=omit_headers)
2615 : END DO
2616 : END DO
2617 : CALL cp_print_key_finished_output(iw, logger, input, &
2618 4 : "DFT%PRINT%AO_MATRICES/KOHN_SHAM_MATRIX")
2619 : END IF
2620 :
2621 : ! write csr matrices
2622 : ! matrices in terms of the PAO basis will be taken care of in pao_post_scf.
2623 11305 : IF (.NOT. dft_control%qs_control%pao) THEN
2624 10793 : CALL write_ks_matrix_csr(qs_env, input)
2625 10793 : CALL write_s_matrix_csr(qs_env, input)
2626 10793 : CALL write_hcore_matrix_csr(qs_env, input)
2627 10793 : CALL write_p_matrix_csr(qs_env, input)
2628 : END IF
2629 :
2630 : ! write adjacency matrix
2631 11305 : CALL write_adjacency_matrix(qs_env, input)
2632 :
2633 : ! Write the xc matrix
2634 11305 : IF (write_xc) THEN
2635 0 : CALL get_qs_env(qs_env=qs_env, matrix_vxc_kp=matrix_vxc)
2636 0 : CPASSERT(ASSOCIATED(matrix_vxc))
2637 : iw = cp_print_key_unit_nr(logger, input, "DFT%PRINT%AO_MATRICES/MATRIX_VXC", &
2638 0 : extension=".Log")
2639 0 : CALL section_vals_val_get(input, "DFT%PRINT%AO_MATRICES%NDIGITS", i_val=after)
2640 0 : after = MIN(MAX(after, 1), 16)
2641 0 : DO ispin = 1, dft_control%nspins
2642 0 : DO img = 1, dft_control%nimages
2643 : CALL cp_dbcsr_write_sparse_matrix(matrix_vxc(ispin, img)%matrix, 4, after, qs_env, &
2644 0 : para_env, output_unit=iw, omit_headers=omit_headers)
2645 : END DO
2646 : END DO
2647 : CALL cp_print_key_finished_output(iw, logger, input, &
2648 0 : "DFT%PRINT%AO_MATRICES/MATRIX_VXC")
2649 : END IF
2650 :
2651 : ! Write the [H,r] commutator matrices
2652 11305 : IF (BTEST(cp_print_key_should_output(logger%iter_info, input, &
2653 : "DFT%PRINT%AO_MATRICES/COMMUTATOR_HR"), cp_p_file)) THEN
2654 : iw = cp_print_key_unit_nr(logger, input, "DFT%PRINT%AO_MATRICES/COMMUTATOR_HR", &
2655 0 : extension=".Log")
2656 0 : CALL section_vals_val_get(input, "DFT%PRINT%AO_MATRICES%NDIGITS", i_val=after)
2657 0 : NULLIFY (matrix_hr)
2658 0 : CALL build_com_hr_matrix(qs_env, matrix_hr)
2659 0 : after = MIN(MAX(after, 1), 16)
2660 0 : DO img = 1, 3
2661 : CALL cp_dbcsr_write_sparse_matrix(matrix_hr(img)%matrix, 4, after, qs_env, &
2662 0 : para_env, output_unit=iw, omit_headers=omit_headers)
2663 : END DO
2664 0 : CALL dbcsr_deallocate_matrix_set(matrix_hr)
2665 : CALL cp_print_key_finished_output(iw, logger, input, &
2666 0 : "DFT%PRINT%AO_MATRICES/COMMUTATOR_HR")
2667 : END IF
2668 :
2669 : ! Compute the Mulliken charges
2670 11305 : print_key => section_vals_get_subs_vals(input, "DFT%PRINT%MULLIKEN")
2671 11305 : IF (BTEST(cp_print_key_should_output(logger%iter_info, print_key), cp_p_file)) THEN
2672 4792 : unit_nr = cp_print_key_unit_nr(logger, input, "DFT%PRINT%MULLIKEN", extension=".mulliken", log_filename=.FALSE.)
2673 4792 : print_level = 1
2674 4792 : CALL section_vals_val_get(print_key, "PRINT_GOP", l_val=print_it)
2675 4792 : IF (print_it) print_level = 2
2676 4792 : CALL section_vals_val_get(print_key, "PRINT_ALL", l_val=print_it)
2677 4792 : IF (print_it) print_level = 3
2678 4792 : CALL mulliken_population_analysis(qs_env, unit_nr, print_level)
2679 4792 : CALL cp_print_key_finished_output(unit_nr, logger, input, "DFT%PRINT%MULLIKEN")
2680 : END IF
2681 :
2682 : ! Compute the Hirshfeld charges
2683 11305 : print_key => section_vals_get_subs_vals(input, "DFT%PRINT%HIRSHFELD")
2684 11305 : IF (BTEST(cp_print_key_should_output(logger%iter_info, print_key), cp_p_file)) THEN
2685 : ! we check if real space density is available
2686 4864 : NULLIFY (rho)
2687 4864 : CALL get_qs_env(qs_env=qs_env, rho=rho)
2688 4864 : CALL qs_rho_get(rho, rho_r_valid=rho_r_valid)
2689 4864 : IF (rho_r_valid) THEN
2690 4790 : unit_nr = cp_print_key_unit_nr(logger, input, "DFT%PRINT%HIRSHFELD", extension=".hirshfeld", log_filename=.FALSE.)
2691 4790 : CALL hirshfeld_charges(qs_env, print_key, unit_nr)
2692 4790 : CALL cp_print_key_finished_output(unit_nr, logger, input, "DFT%PRINT%HIRSHFELD")
2693 : END IF
2694 : END IF
2695 :
2696 : ! Compute EEQ charges
2697 11305 : print_key => section_vals_get_subs_vals(input, "DFT%PRINT%EEQ_CHARGES")
2698 11305 : IF (BTEST(cp_print_key_should_output(logger%iter_info, print_key), cp_p_file)) THEN
2699 30 : unit_nr = cp_print_key_unit_nr(logger, input, "DFT%PRINT%EEQ_CHARGES", extension=".eeq", log_filename=.FALSE.)
2700 30 : print_level = 1
2701 30 : CALL eeq_print(qs_env, unit_nr, print_level, ext=.FALSE.)
2702 30 : CALL cp_print_key_finished_output(unit_nr, logger, input, "DFT%PRINT%MULLIKEN")
2703 : END IF
2704 :
2705 : ! Do a Voronoi Integration or write a compressed BQB File
2706 11305 : print_key_voro => section_vals_get_subs_vals(input, "DFT%PRINT%VORONOI")
2707 11305 : print_key_bqb => section_vals_get_subs_vals(input, "DFT%PRINT%E_DENSITY_BQB")
2708 11305 : IF (BTEST(cp_print_key_should_output(logger%iter_info, print_key_voro), cp_p_file)) THEN
2709 24 : should_print_voro = 1
2710 : ELSE
2711 11281 : should_print_voro = 0
2712 : END IF
2713 11305 : IF (BTEST(cp_print_key_should_output(logger%iter_info, print_key_bqb), cp_p_file)) THEN
2714 2 : should_print_bqb = 1
2715 : ELSE
2716 11303 : should_print_bqb = 0
2717 : END IF
2718 11305 : IF ((should_print_voro /= 0) .OR. (should_print_bqb /= 0)) THEN
2719 :
2720 : ! we check if real space density is available
2721 26 : NULLIFY (rho)
2722 26 : CALL get_qs_env(qs_env=qs_env, rho=rho)
2723 26 : CALL qs_rho_get(rho, rho_r_valid=rho_r_valid)
2724 26 : IF (rho_r_valid) THEN
2725 :
2726 26 : IF (dft_control%nspins > 1) THEN
2727 : CALL get_qs_env(qs_env=qs_env, &
2728 0 : pw_env=pw_env)
2729 : CALL pw_env_get(pw_env=pw_env, &
2730 : auxbas_pw_pool=auxbas_pw_pool, &
2731 0 : pw_pools=pw_pools)
2732 0 : NULLIFY (mb_rho)
2733 0 : ALLOCATE (mb_rho)
2734 0 : CALL auxbas_pw_pool%create_pw(pw=mb_rho)
2735 0 : CALL pw_copy(rho_r(1), mb_rho)
2736 0 : CALL pw_axpy(rho_r(2), mb_rho)
2737 : !CALL voronoi_analysis(qs_env, rho_elec_rspace, print_key, unit_nr)
2738 : ELSE
2739 26 : mb_rho => rho_r(1)
2740 : !CALL voronoi_analysis( qs_env, rho_r(1), print_key, unit_nr )
2741 : END IF ! nspins
2742 :
2743 26 : IF (should_print_voro /= 0) THEN
2744 24 : CALL section_vals_val_get(print_key_voro, "OUTPUT_TEXT", l_val=voro_print_txt)
2745 24 : IF (voro_print_txt) THEN
2746 24 : append_voro = section_get_lval(input, "DFT%PRINT%VORONOI%APPEND")
2747 24 : my_pos_voro = "REWIND"
2748 24 : IF (append_voro) THEN
2749 0 : my_pos_voro = "APPEND"
2750 : END IF
2751 : unit_nr_voro = cp_print_key_unit_nr(logger, input, "DFT%PRINT%VORONOI", extension=".voronoi", &
2752 24 : file_position=my_pos_voro, log_filename=.FALSE.)
2753 : ELSE
2754 0 : unit_nr_voro = 0
2755 : END IF
2756 : ELSE
2757 2 : unit_nr_voro = 0
2758 : END IF
2759 :
2760 : CALL entry_voronoi_or_bqb(should_print_voro, should_print_bqb, print_key_voro, print_key_bqb, &
2761 26 : unit_nr_voro, qs_env, mb_rho)
2762 :
2763 26 : IF (dft_control%nspins > 1) THEN
2764 0 : CALL auxbas_pw_pool%give_back_pw(mb_rho)
2765 0 : DEALLOCATE (mb_rho)
2766 : END IF
2767 :
2768 26 : IF (unit_nr_voro > 0) THEN
2769 12 : CALL cp_print_key_finished_output(unit_nr_voro, logger, input, "DFT%PRINT%VORONOI")
2770 : END IF
2771 :
2772 : END IF
2773 : END IF
2774 :
2775 : ! MAO analysis
2776 11305 : print_key => section_vals_get_subs_vals(input, "DFT%PRINT%MAO_ANALYSIS")
2777 11305 : IF (BTEST(cp_print_key_should_output(logger%iter_info, print_key), cp_p_file)) THEN
2778 38 : unit_nr = cp_print_key_unit_nr(logger, input, "DFT%PRINT%MAO_ANALYSIS", extension=".mao", log_filename=.FALSE.)
2779 38 : CALL mao_analysis(qs_env, print_key, unit_nr)
2780 38 : CALL cp_print_key_finished_output(unit_nr, logger, input, "DFT%PRINT%MAO_ANALYSIS")
2781 : END IF
2782 :
2783 : ! MINBAS analysis
2784 11305 : print_key => section_vals_get_subs_vals(input, "DFT%PRINT%MINBAS_ANALYSIS")
2785 11305 : IF (BTEST(cp_print_key_should_output(logger%iter_info, print_key), cp_p_file)) THEN
2786 28 : unit_nr = cp_print_key_unit_nr(logger, input, "DFT%PRINT%MINBAS_ANALYSIS", extension=".mao", log_filename=.FALSE.)
2787 28 : CALL minbas_analysis(qs_env, print_key, unit_nr)
2788 28 : CALL cp_print_key_finished_output(unit_nr, logger, input, "DFT%PRINT%MINBAS_ANALYSIS")
2789 : END IF
2790 :
2791 : ! IAO analysis
2792 11305 : print_key => section_vals_get_subs_vals(input, "DFT%PRINT%IAO_ANALYSIS")
2793 11305 : IF (BTEST(cp_print_key_should_output(logger%iter_info, print_key), cp_p_file)) THEN
2794 32 : unit_nr = cp_print_key_unit_nr(logger, input, "DFT%PRINT%IAO_ANALYSIS", extension=".iao", log_filename=.FALSE.)
2795 32 : CALL iao_read_input(iao_env, print_key, cell)
2796 32 : IF (iao_env%do_iao) THEN
2797 4 : CALL iao_wfn_analysis(qs_env, iao_env, unit_nr)
2798 : END IF
2799 32 : CALL cp_print_key_finished_output(unit_nr, logger, input, "DFT%PRINT%IAO_ANALYSIS")
2800 : END IF
2801 :
2802 : ! Energy Decomposition Analysis
2803 11305 : print_key => section_vals_get_subs_vals(input, "DFT%PRINT%ENERGY_DECOMPOSITION_ANALYSIS")
2804 11305 : IF (BTEST(cp_print_key_should_output(logger%iter_info, print_key), cp_p_file)) THEN
2805 : unit_nr = cp_print_key_unit_nr(logger, input, "DFT%PRINT%ENERGY_DECOMPOSITION_ANALYSIS", &
2806 58 : extension=".mao", log_filename=.FALSE.)
2807 58 : CALL edmf_analysis(qs_env, print_key, unit_nr)
2808 58 : CALL cp_print_key_finished_output(unit_nr, logger, input, "DFT%PRINT%ENERGY_DECOMPOSITION_ANALYSIS")
2809 : END IF
2810 :
2811 : ! Print the density in the RI-HFX basis
2812 11305 : hfx_section => section_vals_get_subs_vals(input, "DFT%XC%HF")
2813 11305 : CALL section_vals_get(hfx_section, explicit=do_hfx)
2814 11305 : CALL section_vals_get(hfx_section, n_repetition=n_rep_hf)
2815 11305 : IF (do_hfx) THEN
2816 4526 : DO i = 1, n_rep_hf
2817 4526 : IF (qs_env%x_data(i, 1)%do_hfx_ri) CALL print_ri_hfx(qs_env%x_data(i, 1)%ri_data, qs_env)
2818 : END DO
2819 : END IF
2820 :
2821 11305 : DEALLOCATE (zcharge)
2822 :
2823 11305 : CALL timestop(handle)
2824 :
2825 45220 : END SUBROUTINE write_mo_free_results
2826 :
2827 : ! **************************************************************************************************
2828 : !> \brief Calculates Hirshfeld charges
2829 : !> \param qs_env the qs_env where to calculate the charges
2830 : !> \param input_section the input section for Hirshfeld charges
2831 : !> \param unit_nr the output unit number
2832 : ! **************************************************************************************************
2833 4790 : SUBROUTINE hirshfeld_charges(qs_env, input_section, unit_nr)
2834 : TYPE(qs_environment_type), POINTER :: qs_env
2835 : TYPE(section_vals_type), POINTER :: input_section
2836 : INTEGER, INTENT(IN) :: unit_nr
2837 :
2838 : INTEGER :: i, iat, ikind, natom, nkind, nspin, &
2839 : radius_type, refc, shapef
2840 4790 : INTEGER, DIMENSION(:), POINTER :: atom_list
2841 : LOGICAL :: do_radius, do_sc, paw_atom
2842 : REAL(KIND=dp) :: zeff
2843 4790 : REAL(KIND=dp), DIMENSION(:), POINTER :: radii
2844 4790 : REAL(KIND=dp), DIMENSION(:, :), POINTER :: charges
2845 4790 : TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
2846 : TYPE(atomic_kind_type), POINTER :: atomic_kind
2847 4790 : TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: matrix_p, matrix_s
2848 : TYPE(dft_control_type), POINTER :: dft_control
2849 : TYPE(hirshfeld_type), POINTER :: hirshfeld_env
2850 : TYPE(mp_para_env_type), POINTER :: para_env
2851 4790 : TYPE(mpole_rho_atom), DIMENSION(:), POINTER :: mp_rho
2852 4790 : TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
2853 4790 : TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
2854 : TYPE(qs_rho_type), POINTER :: rho
2855 : TYPE(rho0_mpole_type), POINTER :: rho0_mpole
2856 :
2857 4790 : NULLIFY (hirshfeld_env)
2858 4790 : NULLIFY (radii)
2859 4790 : CALL create_hirshfeld_type(hirshfeld_env)
2860 : !
2861 4790 : CALL get_qs_env(qs_env, nkind=nkind, natom=natom)
2862 14370 : ALLOCATE (hirshfeld_env%charges(natom))
2863 : ! input options
2864 4790 : CALL section_vals_val_get(input_section, "SELF_CONSISTENT", l_val=do_sc)
2865 4790 : CALL section_vals_val_get(input_section, "USER_RADIUS", l_val=do_radius)
2866 4790 : CALL section_vals_val_get(input_section, "SHAPE_FUNCTION", i_val=shapef)
2867 4790 : CALL section_vals_val_get(input_section, "REFERENCE_CHARGE", i_val=refc)
2868 4790 : IF (do_radius) THEN
2869 0 : radius_type = radius_user
2870 0 : CALL section_vals_val_get(input_section, "ATOMIC_RADII", r_vals=radii)
2871 0 : IF (.NOT. SIZE(radii) == nkind) &
2872 : CALL cp_abort(__LOCATION__, &
2873 : "Length of keyword HIRSHFELD\ATOMIC_RADII does not "// &
2874 0 : "match number of atomic kinds in the input coordinate file.")
2875 : ELSE
2876 4790 : radius_type = radius_covalent
2877 : END IF
2878 : CALL set_hirshfeld_info(hirshfeld_env, shape_function_type=shapef, &
2879 : iterative=do_sc, ref_charge=refc, &
2880 4790 : radius_type=radius_type)
2881 : ! shape function
2882 4790 : CALL get_qs_env(qs_env, qs_kind_set=qs_kind_set, atomic_kind_set=atomic_kind_set)
2883 : CALL create_shape_function(hirshfeld_env, qs_kind_set, atomic_kind_set, &
2884 4790 : radii_list=radii)
2885 : ! reference charges
2886 4790 : CALL get_qs_env(qs_env, rho=rho)
2887 4790 : CALL qs_rho_get(rho, rho_ao_kp=matrix_p)
2888 4790 : nspin = SIZE(matrix_p, 1)
2889 19160 : ALLOCATE (charges(natom, nspin))
2890 4778 : SELECT CASE (refc)
2891 : CASE (ref_charge_atomic)
2892 13086 : DO ikind = 1, nkind
2893 8308 : CALL get_qs_kind(qs_kind_set(ikind), zeff=zeff)
2894 8308 : atomic_kind => atomic_kind_set(ikind)
2895 8308 : CALL get_atomic_kind(atomic_kind, atom_list=atom_list)
2896 41380 : DO iat = 1, SIZE(atom_list)
2897 19986 : i = atom_list(iat)
2898 28294 : hirshfeld_env%charges(i) = zeff
2899 : END DO
2900 : END DO
2901 : CASE (ref_charge_mulliken)
2902 12 : CALL get_qs_env(qs_env, matrix_s_kp=matrix_s, para_env=para_env)
2903 12 : CALL mulliken_charges(matrix_p, matrix_s, para_env, charges)
2904 48 : DO iat = 1, natom
2905 108 : hirshfeld_env%charges(iat) = SUM(charges(iat, :))
2906 : END DO
2907 : CASE DEFAULT
2908 4790 : CPABORT("Unknown type of reference charge for Hirshfeld partitioning.")
2909 : END SELECT
2910 : !
2911 33314 : charges = 0.0_dp
2912 4790 : IF (hirshfeld_env%iterative) THEN
2913 : ! Hirshfeld-I charges
2914 22 : CALL comp_hirshfeld_i_charges(qs_env, hirshfeld_env, charges, unit_nr)
2915 : ELSE
2916 : ! Hirshfeld charges
2917 4768 : CALL comp_hirshfeld_charges(qs_env, hirshfeld_env, charges)
2918 : END IF
2919 4790 : CALL get_qs_env(qs_env, particle_set=particle_set, dft_control=dft_control)
2920 4790 : IF (dft_control%qs_control%gapw) THEN
2921 : ! GAPW: add core charges (rho_hard - rho_soft)
2922 698 : CALL get_qs_env(qs_env, rho0_mpole=rho0_mpole)
2923 698 : CALL get_rho0_mpole(rho0_mpole, mp_rho=mp_rho)
2924 3088 : DO iat = 1, natom
2925 2390 : atomic_kind => particle_set(iat)%atomic_kind
2926 2390 : CALL get_atomic_kind(atomic_kind, kind_number=ikind)
2927 2390 : CALL get_qs_kind(qs_kind_set(ikind), paw_atom=paw_atom)
2928 3088 : IF (paw_atom) THEN
2929 4574 : charges(iat, 1:nspin) = charges(iat, 1:nspin) + mp_rho(iat)%q0(1:nspin)
2930 : END IF
2931 : END DO
2932 : END IF
2933 : !
2934 4790 : IF (unit_nr > 0) THEN
2935 : CALL write_hirshfeld_charges(charges, hirshfeld_env, particle_set, &
2936 2409 : qs_kind_set, unit_nr)
2937 : END IF
2938 : ! Save the charges to the results under the tag [HIRSHFELD-CHARGES]
2939 4790 : CALL save_hirshfeld_charges(charges, particle_set, qs_kind_set, qs_env)
2940 : !
2941 4790 : CALL release_hirshfeld_type(hirshfeld_env)
2942 4790 : DEALLOCATE (charges)
2943 :
2944 9580 : END SUBROUTINE hirshfeld_charges
2945 :
2946 : ! **************************************************************************************************
2947 : !> \brief ...
2948 : !> \param ca ...
2949 : !> \param a ...
2950 : !> \param cb ...
2951 : !> \param b ...
2952 : !> \param l ...
2953 : ! **************************************************************************************************
2954 4 : SUBROUTINE project_function_a(ca, a, cb, b, l)
2955 : ! project function cb on ca
2956 : REAL(KIND=dp), DIMENSION(:), INTENT(OUT) :: ca
2957 : REAL(KIND=dp), DIMENSION(:), INTENT(IN) :: a, cb, b
2958 : INTEGER, INTENT(IN) :: l
2959 :
2960 : INTEGER :: info, n
2961 4 : INTEGER, ALLOCATABLE, DIMENSION(:) :: ipiv
2962 4 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :) :: smat, tmat, v
2963 :
2964 4 : n = SIZE(ca)
2965 40 : ALLOCATE (smat(n, n), tmat(n, n), v(n, 1), ipiv(n))
2966 :
2967 4 : CALL sg_overlap(smat, l, a, a)
2968 4 : CALL sg_overlap(tmat, l, a, b)
2969 1252 : v(:, 1) = MATMUL(tmat, cb)
2970 4 : CALL dgesv(n, 1, smat, n, ipiv, v, n, info)
2971 4 : CPASSERT(info == 0)
2972 52 : ca(:) = v(:, 1)
2973 :
2974 4 : DEALLOCATE (smat, tmat, v, ipiv)
2975 :
2976 4 : END SUBROUTINE project_function_a
2977 :
2978 : ! **************************************************************************************************
2979 : !> \brief ...
2980 : !> \param ca ...
2981 : !> \param a ...
2982 : !> \param bfun ...
2983 : !> \param grid_atom ...
2984 : !> \param l ...
2985 : ! **************************************************************************************************
2986 36 : SUBROUTINE project_function_b(ca, a, bfun, grid_atom, l)
2987 : ! project function f on ca
2988 : REAL(KIND=dp), DIMENSION(:), INTENT(OUT) :: ca
2989 : REAL(KIND=dp), DIMENSION(:), INTENT(IN) :: a, bfun
2990 : TYPE(grid_atom_type), POINTER :: grid_atom
2991 : INTEGER, INTENT(IN) :: l
2992 :
2993 : INTEGER :: i, info, n, nr
2994 36 : INTEGER, ALLOCATABLE, DIMENSION(:) :: ipiv
2995 36 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:) :: afun
2996 36 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :) :: smat, v
2997 :
2998 36 : n = SIZE(ca)
2999 36 : nr = grid_atom%nr
3000 360 : ALLOCATE (smat(n, n), v(n, 1), ipiv(n), afun(nr))
3001 :
3002 36 : CALL sg_overlap(smat, l, a, a)
3003 468 : DO i = 1, n
3004 22032 : afun(:) = grid_atom%rad(:)**l*EXP(-a(i)*grid_atom%rad2(:))
3005 22068 : v(i, 1) = SUM(afun(:)*bfun(:)*grid_atom%wr(:))
3006 : END DO
3007 36 : CALL dgesv(n, 1, smat, n, ipiv, v, n, info)
3008 36 : CPASSERT(info == 0)
3009 468 : ca(:) = v(:, 1)
3010 :
3011 36 : DEALLOCATE (smat, v, ipiv, afun)
3012 :
3013 36 : END SUBROUTINE project_function_b
3014 :
3015 : ! **************************************************************************************************
3016 : !> \brief Performs printing of cube files from local energy
3017 : !> \param input input
3018 : !> \param logger the logger
3019 : !> \param qs_env the qs_env in which the qs_env lives
3020 : !> \par History
3021 : !> 07.2019 created
3022 : !> \author JGH
3023 : ! **************************************************************************************************
3024 11305 : SUBROUTINE qs_scf_post_local_energy(input, logger, qs_env)
3025 : TYPE(section_vals_type), POINTER :: input
3026 : TYPE(cp_logger_type), POINTER :: logger
3027 : TYPE(qs_environment_type), POINTER :: qs_env
3028 :
3029 : CHARACTER(len=*), PARAMETER :: routineN = 'qs_scf_post_local_energy'
3030 :
3031 : CHARACTER(LEN=default_path_length) :: filename, my_pos_cube
3032 : INTEGER :: handle, io_unit, natom, unit_nr
3033 : LOGICAL :: append_cube, gapw, gapw_xc, mpi_io
3034 : TYPE(dft_control_type), POINTER :: dft_control
3035 : TYPE(particle_list_type), POINTER :: particles
3036 : TYPE(pw_env_type), POINTER :: pw_env
3037 : TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
3038 : TYPE(pw_r3d_rs_type) :: eden
3039 : TYPE(qs_subsys_type), POINTER :: subsys
3040 : TYPE(section_vals_type), POINTER :: dft_section
3041 :
3042 11305 : CALL timeset(routineN, handle)
3043 11305 : io_unit = cp_logger_get_default_io_unit(logger)
3044 11305 : IF (BTEST(cp_print_key_should_output(logger%iter_info, input, &
3045 : "DFT%PRINT%LOCAL_ENERGY_CUBE"), cp_p_file)) THEN
3046 32 : dft_section => section_vals_get_subs_vals(input, "DFT")
3047 32 : CALL get_qs_env(qs_env=qs_env, dft_control=dft_control, natom=natom)
3048 32 : gapw = dft_control%qs_control%gapw
3049 32 : gapw_xc = dft_control%qs_control%gapw_xc
3050 32 : CALL get_qs_env(qs_env=qs_env, pw_env=pw_env, subsys=subsys)
3051 32 : CALL qs_subsys_get(subsys, particles=particles)
3052 32 : CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool)
3053 32 : CALL auxbas_pw_pool%create_pw(eden)
3054 : !
3055 32 : CALL qs_local_energy(qs_env, eden)
3056 : !
3057 32 : append_cube = section_get_lval(input, "DFT%PRINT%LOCAL_ENERGY_CUBE%APPEND")
3058 32 : IF (append_cube) THEN
3059 0 : my_pos_cube = "APPEND"
3060 : ELSE
3061 32 : my_pos_cube = "REWIND"
3062 : END IF
3063 32 : mpi_io = .TRUE.
3064 : unit_nr = cp_print_key_unit_nr(logger, input, "DFT%PRINT%LOCAL_ENERGY_CUBE", &
3065 : extension=".cube", middle_name="local_energy", &
3066 32 : file_position=my_pos_cube, mpi_io=mpi_io)
3067 : CALL cp_pw_to_cube(eden, &
3068 : unit_nr, "LOCAL ENERGY", particles=particles, &
3069 : stride=section_get_ivals(dft_section, &
3070 32 : "PRINT%LOCAL_ENERGY_CUBE%STRIDE"), mpi_io=mpi_io)
3071 32 : IF (io_unit > 0) THEN
3072 16 : INQUIRE (UNIT=unit_nr, NAME=filename)
3073 16 : IF (gapw .OR. gapw_xc) THEN
3074 : WRITE (UNIT=io_unit, FMT="(/,T3,A,A)") &
3075 0 : "The soft part of the local energy is written to the file: ", TRIM(ADJUSTL(filename))
3076 : ELSE
3077 : WRITE (UNIT=io_unit, FMT="(/,T3,A,A)") &
3078 16 : "The local energy is written to the file: ", TRIM(ADJUSTL(filename))
3079 : END IF
3080 : END IF
3081 : CALL cp_print_key_finished_output(unit_nr, logger, input, &
3082 32 : "DFT%PRINT%LOCAL_ENERGY_CUBE", mpi_io=mpi_io)
3083 : !
3084 32 : CALL auxbas_pw_pool%give_back_pw(eden)
3085 : END IF
3086 11305 : CALL timestop(handle)
3087 :
3088 11305 : END SUBROUTINE qs_scf_post_local_energy
3089 :
3090 : ! **************************************************************************************************
3091 : !> \brief Performs printing of cube files from local energy
3092 : !> \param input input
3093 : !> \param logger the logger
3094 : !> \param qs_env the qs_env in which the qs_env lives
3095 : !> \par History
3096 : !> 07.2019 created
3097 : !> \author JGH
3098 : ! **************************************************************************************************
3099 11305 : SUBROUTINE qs_scf_post_local_stress(input, logger, qs_env)
3100 : TYPE(section_vals_type), POINTER :: input
3101 : TYPE(cp_logger_type), POINTER :: logger
3102 : TYPE(qs_environment_type), POINTER :: qs_env
3103 :
3104 : CHARACTER(len=*), PARAMETER :: routineN = 'qs_scf_post_local_stress'
3105 :
3106 : CHARACTER(LEN=default_path_length) :: filename, my_pos_cube
3107 : INTEGER :: handle, io_unit, natom, unit_nr
3108 : LOGICAL :: append_cube, gapw, gapw_xc, mpi_io
3109 : REAL(KIND=dp) :: beta
3110 : TYPE(dft_control_type), POINTER :: dft_control
3111 : TYPE(particle_list_type), POINTER :: particles
3112 : TYPE(pw_env_type), POINTER :: pw_env
3113 : TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
3114 : TYPE(pw_r3d_rs_type) :: stress
3115 : TYPE(qs_subsys_type), POINTER :: subsys
3116 : TYPE(section_vals_type), POINTER :: dft_section
3117 :
3118 11305 : CALL timeset(routineN, handle)
3119 11305 : io_unit = cp_logger_get_default_io_unit(logger)
3120 11305 : IF (BTEST(cp_print_key_should_output(logger%iter_info, input, &
3121 : "DFT%PRINT%LOCAL_STRESS_CUBE"), cp_p_file)) THEN
3122 30 : dft_section => section_vals_get_subs_vals(input, "DFT")
3123 30 : CALL get_qs_env(qs_env=qs_env, dft_control=dft_control, natom=natom)
3124 30 : gapw = dft_control%qs_control%gapw
3125 30 : gapw_xc = dft_control%qs_control%gapw_xc
3126 30 : CALL get_qs_env(qs_env=qs_env, pw_env=pw_env, subsys=subsys)
3127 30 : CALL qs_subsys_get(subsys, particles=particles)
3128 30 : CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool)
3129 30 : CALL auxbas_pw_pool%create_pw(stress)
3130 : !
3131 : ! use beta=0: kinetic energy density in symmetric form
3132 30 : beta = 0.0_dp
3133 30 : CALL qs_local_stress(qs_env, beta=beta)
3134 : !
3135 30 : append_cube = section_get_lval(input, "DFT%PRINT%LOCAL_STRESS_CUBE%APPEND")
3136 30 : IF (append_cube) THEN
3137 0 : my_pos_cube = "APPEND"
3138 : ELSE
3139 30 : my_pos_cube = "REWIND"
3140 : END IF
3141 30 : mpi_io = .TRUE.
3142 : unit_nr = cp_print_key_unit_nr(logger, input, "DFT%PRINT%LOCAL_STRESS_CUBE", &
3143 : extension=".cube", middle_name="local_stress", &
3144 30 : file_position=my_pos_cube, mpi_io=mpi_io)
3145 : CALL cp_pw_to_cube(stress, &
3146 : unit_nr, "LOCAL STRESS", particles=particles, &
3147 : stride=section_get_ivals(dft_section, &
3148 30 : "PRINT%LOCAL_STRESS_CUBE%STRIDE"), mpi_io=mpi_io)
3149 30 : IF (io_unit > 0) THEN
3150 15 : INQUIRE (UNIT=unit_nr, NAME=filename)
3151 15 : WRITE (UNIT=io_unit, FMT="(/,T3,A)") "Write 1/3*Tr(sigma) to cube file"
3152 15 : IF (gapw .OR. gapw_xc) THEN
3153 : WRITE (UNIT=io_unit, FMT="(T3,A,A)") &
3154 0 : "The soft part of the local stress is written to the file: ", TRIM(ADJUSTL(filename))
3155 : ELSE
3156 : WRITE (UNIT=io_unit, FMT="(T3,A,A)") &
3157 15 : "The local stress is written to the file: ", TRIM(ADJUSTL(filename))
3158 : END IF
3159 : END IF
3160 : CALL cp_print_key_finished_output(unit_nr, logger, input, &
3161 30 : "DFT%PRINT%LOCAL_STRESS_CUBE", mpi_io=mpi_io)
3162 : !
3163 30 : CALL auxbas_pw_pool%give_back_pw(stress)
3164 : END IF
3165 :
3166 11305 : CALL timestop(handle)
3167 :
3168 11305 : END SUBROUTINE qs_scf_post_local_stress
3169 :
3170 : ! **************************************************************************************************
3171 : !> \brief Performs printing of cube files related to the implicit Poisson solver
3172 : !> \param input input
3173 : !> \param logger the logger
3174 : !> \param qs_env the qs_env in which the qs_env lives
3175 : !> \par History
3176 : !> 03.2016 refactored from write_mo_free_results [Hossein Bani-Hashemian]
3177 : !> \author Mohammad Hossein Bani-Hashemian
3178 : ! **************************************************************************************************
3179 11305 : SUBROUTINE qs_scf_post_ps_implicit(input, logger, qs_env)
3180 : TYPE(section_vals_type), POINTER :: input
3181 : TYPE(cp_logger_type), POINTER :: logger
3182 : TYPE(qs_environment_type), POINTER :: qs_env
3183 :
3184 : CHARACTER(len=*), PARAMETER :: routineN = 'qs_scf_post_ps_implicit'
3185 :
3186 : CHARACTER(LEN=default_path_length) :: filename, my_pos_cube
3187 : INTEGER :: boundary_condition, handle, i, j, &
3188 : n_cstr, n_tiles, unit_nr
3189 : LOGICAL :: append_cube, do_cstr_charge_cube, do_dielectric_cube, do_dirichlet_bc_cube, &
3190 : has_dirichlet_bc, has_implicit_ps, mpi_io, tile_cubes
3191 : TYPE(particle_list_type), POINTER :: particles
3192 : TYPE(pw_env_type), POINTER :: pw_env
3193 : TYPE(pw_poisson_type), POINTER :: poisson_env
3194 : TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
3195 : TYPE(pw_r3d_rs_type) :: aux_r
3196 : TYPE(pw_r3d_rs_type), POINTER :: dirichlet_tile
3197 : TYPE(qs_subsys_type), POINTER :: subsys
3198 : TYPE(section_vals_type), POINTER :: dft_section
3199 :
3200 11305 : CALL timeset(routineN, handle)
3201 :
3202 11305 : NULLIFY (pw_env, auxbas_pw_pool, dft_section, particles)
3203 :
3204 11305 : dft_section => section_vals_get_subs_vals(input, "DFT")
3205 11305 : CALL get_qs_env(qs_env=qs_env, pw_env=pw_env, subsys=subsys)
3206 11305 : CALL qs_subsys_get(subsys, particles=particles)
3207 11305 : CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool)
3208 :
3209 11305 : has_implicit_ps = .FALSE.
3210 11305 : CALL get_qs_env(qs_env=qs_env, pw_env=pw_env)
3211 11305 : IF (pw_env%poisson_env%parameters%solver == pw_poisson_implicit) has_implicit_ps = .TRUE.
3212 :
3213 : ! Write the dielectric constant into a cube file
3214 : do_dielectric_cube = BTEST(cp_print_key_should_output(logger%iter_info, input, &
3215 11305 : "DFT%PRINT%IMPLICIT_PSOLVER%DIELECTRIC_CUBE"), cp_p_file)
3216 11305 : IF (has_implicit_ps .AND. do_dielectric_cube) THEN
3217 0 : append_cube = section_get_lval(input, "DFT%PRINT%IMPLICIT_PSOLVER%DIELECTRIC_CUBE%APPEND")
3218 0 : my_pos_cube = "REWIND"
3219 0 : IF (append_cube) THEN
3220 0 : my_pos_cube = "APPEND"
3221 : END IF
3222 0 : mpi_io = .TRUE.
3223 : unit_nr = cp_print_key_unit_nr(logger, input, "DFT%PRINT%IMPLICIT_PSOLVER%DIELECTRIC_CUBE", &
3224 : extension=".cube", middle_name="DIELECTRIC_CONSTANT", file_position=my_pos_cube, &
3225 0 : mpi_io=mpi_io)
3226 0 : CALL pw_env_get(pw_env, poisson_env=poisson_env, auxbas_pw_pool=auxbas_pw_pool)
3227 0 : CALL auxbas_pw_pool%create_pw(aux_r)
3228 :
3229 0 : boundary_condition = pw_env%poisson_env%parameters%ps_implicit_params%boundary_condition
3230 0 : SELECT CASE (boundary_condition)
3231 : CASE (PERIODIC_BC, MIXED_PERIODIC_BC)
3232 0 : CALL pw_copy(poisson_env%implicit_env%dielectric%eps, aux_r)
3233 : CASE (MIXED_BC, NEUMANN_BC)
3234 : CALL pw_shrink(pw_env%poisson_env%parameters%ps_implicit_params%neumann_directions, &
3235 : pw_env%poisson_env%implicit_env%dct_env%dests_shrink, &
3236 : pw_env%poisson_env%implicit_env%dct_env%srcs_shrink, &
3237 : pw_env%poisson_env%implicit_env%dct_env%bounds_local_shftd, &
3238 0 : poisson_env%implicit_env%dielectric%eps, aux_r)
3239 : END SELECT
3240 :
3241 : CALL cp_pw_to_cube(aux_r, unit_nr, "DIELECTRIC CONSTANT", particles=particles, &
3242 : stride=section_get_ivals(dft_section, "PRINT%IMPLICIT_PSOLVER%DIELECTRIC_CUBE%STRIDE"), &
3243 0 : mpi_io=mpi_io)
3244 : CALL cp_print_key_finished_output(unit_nr, logger, input, &
3245 0 : "DFT%PRINT%IMPLICIT_PSOLVER%DIELECTRIC_CUBE", mpi_io=mpi_io)
3246 :
3247 0 : CALL auxbas_pw_pool%give_back_pw(aux_r)
3248 : END IF
3249 :
3250 : ! Write Dirichlet constraint charges into a cube file
3251 : do_cstr_charge_cube = BTEST(cp_print_key_should_output(logger%iter_info, input, &
3252 11305 : "DFT%PRINT%IMPLICIT_PSOLVER%DIRICHLET_CSTR_CHARGE_CUBE"), cp_p_file)
3253 :
3254 11305 : has_dirichlet_bc = .FALSE.
3255 11305 : IF (has_implicit_ps) THEN
3256 86 : boundary_condition = pw_env%poisson_env%parameters%ps_implicit_params%boundary_condition
3257 86 : IF (boundary_condition == MIXED_PERIODIC_BC .OR. boundary_condition == MIXED_BC) THEN
3258 60 : has_dirichlet_bc = .TRUE.
3259 : END IF
3260 : END IF
3261 :
3262 11305 : IF (has_implicit_ps .AND. do_cstr_charge_cube .AND. has_dirichlet_bc) THEN
3263 : append_cube = section_get_lval(input, &
3264 0 : "DFT%PRINT%IMPLICIT_PSOLVER%DIRICHLET_CSTR_CHARGE_CUBE%APPEND")
3265 0 : my_pos_cube = "REWIND"
3266 0 : IF (append_cube) THEN
3267 0 : my_pos_cube = "APPEND"
3268 : END IF
3269 0 : mpi_io = .TRUE.
3270 : unit_nr = cp_print_key_unit_nr(logger, input, &
3271 : "DFT%PRINT%IMPLICIT_PSOLVER%DIRICHLET_CSTR_CHARGE_CUBE", &
3272 : extension=".cube", middle_name="dirichlet_cstr_charge", file_position=my_pos_cube, &
3273 0 : mpi_io=mpi_io)
3274 0 : CALL pw_env_get(pw_env, poisson_env=poisson_env, auxbas_pw_pool=auxbas_pw_pool)
3275 0 : CALL auxbas_pw_pool%create_pw(aux_r)
3276 :
3277 0 : boundary_condition = pw_env%poisson_env%parameters%ps_implicit_params%boundary_condition
3278 0 : SELECT CASE (boundary_condition)
3279 : CASE (MIXED_PERIODIC_BC)
3280 0 : CALL pw_copy(poisson_env%implicit_env%cstr_charge, aux_r)
3281 : CASE (MIXED_BC)
3282 : CALL pw_shrink(pw_env%poisson_env%parameters%ps_implicit_params%neumann_directions, &
3283 : pw_env%poisson_env%implicit_env%dct_env%dests_shrink, &
3284 : pw_env%poisson_env%implicit_env%dct_env%srcs_shrink, &
3285 : pw_env%poisson_env%implicit_env%dct_env%bounds_local_shftd, &
3286 0 : poisson_env%implicit_env%cstr_charge, aux_r)
3287 : END SELECT
3288 :
3289 : CALL cp_pw_to_cube(aux_r, unit_nr, "DIRICHLET CONSTRAINT CHARGE", particles=particles, &
3290 : stride=section_get_ivals(dft_section, "PRINT%IMPLICIT_PSOLVER%DIRICHLET_CSTR_CHARGE_CUBE%STRIDE"), &
3291 0 : mpi_io=mpi_io)
3292 : CALL cp_print_key_finished_output(unit_nr, logger, input, &
3293 0 : "DFT%PRINT%IMPLICIT_PSOLVER%DIRICHLET_CSTR_CHARGE_CUBE", mpi_io=mpi_io)
3294 :
3295 0 : CALL auxbas_pw_pool%give_back_pw(aux_r)
3296 : END IF
3297 :
3298 : ! Write Dirichlet type constranits into cube files
3299 : do_dirichlet_bc_cube = BTEST(cp_print_key_should_output(logger%iter_info, input, &
3300 11305 : "DFT%PRINT%IMPLICIT_PSOLVER%DIRICHLET_BC_CUBE"), cp_p_file)
3301 11305 : has_dirichlet_bc = .FALSE.
3302 11305 : IF (has_implicit_ps) THEN
3303 86 : boundary_condition = pw_env%poisson_env%parameters%ps_implicit_params%boundary_condition
3304 86 : IF (boundary_condition == MIXED_PERIODIC_BC .OR. boundary_condition == MIXED_BC) THEN
3305 60 : has_dirichlet_bc = .TRUE.
3306 : END IF
3307 : END IF
3308 :
3309 11305 : IF (has_implicit_ps .AND. has_dirichlet_bc .AND. do_dirichlet_bc_cube) THEN
3310 0 : append_cube = section_get_lval(input, "DFT%PRINT%IMPLICIT_PSOLVER%DIRICHLET_BC_CUBE%APPEND")
3311 0 : my_pos_cube = "REWIND"
3312 0 : IF (append_cube) THEN
3313 0 : my_pos_cube = "APPEND"
3314 : END IF
3315 0 : tile_cubes = section_get_lval(input, "DFT%PRINT%IMPLICIT_PSOLVER%DIRICHLET_BC_CUBE%TILE_CUBES")
3316 :
3317 0 : CALL pw_env_get(pw_env, poisson_env=poisson_env, auxbas_pw_pool=auxbas_pw_pool)
3318 0 : CALL auxbas_pw_pool%create_pw(aux_r)
3319 0 : CALL pw_zero(aux_r)
3320 :
3321 0 : IF (tile_cubes) THEN
3322 : ! one cube file per tile
3323 0 : n_cstr = SIZE(poisson_env%implicit_env%contacts)
3324 0 : DO j = 1, n_cstr
3325 0 : n_tiles = poisson_env%implicit_env%contacts(j)%dirichlet_bc%n_tiles
3326 0 : DO i = 1, n_tiles
3327 : filename = "dirichlet_cstr_"//TRIM(ADJUSTL(cp_to_string(j)))// &
3328 0 : "_tile_"//TRIM(ADJUSTL(cp_to_string(i)))
3329 0 : mpi_io = .TRUE.
3330 : unit_nr = cp_print_key_unit_nr(logger, input, "DFT%PRINT%IMPLICIT_PSOLVER%DIRICHLET_BC_CUBE", &
3331 : extension=".cube", middle_name=filename, file_position=my_pos_cube, &
3332 0 : mpi_io=mpi_io)
3333 :
3334 0 : CALL pw_copy(poisson_env%implicit_env%contacts(j)%dirichlet_bc%tiles(i)%tile%tile_pw, aux_r)
3335 :
3336 : CALL cp_pw_to_cube(aux_r, unit_nr, "DIRICHLET TYPE CONSTRAINT", particles=particles, &
3337 : stride=section_get_ivals(dft_section, "PRINT%IMPLICIT_PSOLVER%DIRICHLET_BC_CUBE%STRIDE"), &
3338 0 : mpi_io=mpi_io)
3339 : CALL cp_print_key_finished_output(unit_nr, logger, input, &
3340 0 : "DFT%PRINT%IMPLICIT_PSOLVER%DIRICHLET_BC_CUBE", mpi_io=mpi_io)
3341 : END DO
3342 : END DO
3343 : ELSE
3344 : ! a single cube file
3345 0 : NULLIFY (dirichlet_tile)
3346 0 : ALLOCATE (dirichlet_tile)
3347 0 : CALL auxbas_pw_pool%create_pw(dirichlet_tile)
3348 0 : CALL pw_zero(dirichlet_tile)
3349 0 : mpi_io = .TRUE.
3350 : unit_nr = cp_print_key_unit_nr(logger, input, "DFT%PRINT%IMPLICIT_PSOLVER%DIRICHLET_BC_CUBE", &
3351 : extension=".cube", middle_name="DIRICHLET_CSTR", file_position=my_pos_cube, &
3352 0 : mpi_io=mpi_io)
3353 :
3354 0 : n_cstr = SIZE(poisson_env%implicit_env%contacts)
3355 0 : DO j = 1, n_cstr
3356 0 : n_tiles = poisson_env%implicit_env%contacts(j)%dirichlet_bc%n_tiles
3357 0 : DO i = 1, n_tiles
3358 0 : CALL pw_copy(poisson_env%implicit_env%contacts(j)%dirichlet_bc%tiles(i)%tile%tile_pw, dirichlet_tile)
3359 0 : CALL pw_axpy(dirichlet_tile, aux_r)
3360 : END DO
3361 : END DO
3362 :
3363 : CALL cp_pw_to_cube(aux_r, unit_nr, "DIRICHLET TYPE CONSTRAINT", particles=particles, &
3364 : stride=section_get_ivals(dft_section, "PRINT%IMPLICIT_PSOLVER%DIRICHLET_BC_CUBE%STRIDE"), &
3365 0 : mpi_io=mpi_io)
3366 : CALL cp_print_key_finished_output(unit_nr, logger, input, &
3367 0 : "DFT%PRINT%IMPLICIT_PSOLVER%DIRICHLET_BC_CUBE", mpi_io=mpi_io)
3368 0 : CALL auxbas_pw_pool%give_back_pw(dirichlet_tile)
3369 0 : DEALLOCATE (dirichlet_tile)
3370 : END IF
3371 :
3372 0 : CALL auxbas_pw_pool%give_back_pw(aux_r)
3373 : END IF
3374 :
3375 11305 : CALL timestop(handle)
3376 :
3377 11305 : END SUBROUTINE qs_scf_post_ps_implicit
3378 :
3379 : !**************************************************************************************************
3380 : !> \brief write an adjacency (interaction) matrix
3381 : !> \param qs_env qs environment
3382 : !> \param input the input
3383 : !> \author Mohammad Hossein Bani-Hashemian
3384 : ! **************************************************************************************************
3385 11305 : SUBROUTINE write_adjacency_matrix(qs_env, input)
3386 : TYPE(qs_environment_type), POINTER :: qs_env
3387 : TYPE(section_vals_type), POINTER :: input
3388 :
3389 : CHARACTER(len=*), PARAMETER :: routineN = 'write_adjacency_matrix'
3390 :
3391 : INTEGER :: adjm_size, colind, handle, iatom, ikind, &
3392 : ind, jatom, jkind, k, natom, nkind, &
3393 : output_unit, rowind, unit_nr
3394 11305 : INTEGER, ALLOCATABLE, DIMENSION(:) :: interact_adjm
3395 : LOGICAL :: do_adjm_write, do_symmetric
3396 : TYPE(cp_logger_type), POINTER :: logger
3397 11305 : TYPE(gto_basis_set_p_type), DIMENSION(:), POINTER :: basis_set_list_a, basis_set_list_b
3398 : TYPE(gto_basis_set_type), POINTER :: basis_set_a, basis_set_b
3399 : TYPE(mp_para_env_type), POINTER :: para_env
3400 : TYPE(neighbor_list_iterator_p_type), &
3401 11305 : DIMENSION(:), POINTER :: nl_iterator
3402 : TYPE(neighbor_list_set_p_type), DIMENSION(:), &
3403 11305 : POINTER :: nl
3404 11305 : TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
3405 : TYPE(section_vals_type), POINTER :: dft_section
3406 :
3407 11305 : CALL timeset(routineN, handle)
3408 :
3409 11305 : NULLIFY (dft_section)
3410 :
3411 11305 : logger => cp_get_default_logger()
3412 11305 : output_unit = cp_logger_get_default_io_unit(logger)
3413 :
3414 11305 : dft_section => section_vals_get_subs_vals(input, "DFT")
3415 : do_adjm_write = BTEST(cp_print_key_should_output(logger%iter_info, dft_section, &
3416 11305 : "PRINT%ADJMAT_WRITE"), cp_p_file)
3417 :
3418 11305 : IF (do_adjm_write) THEN
3419 28 : NULLIFY (qs_kind_set, nl_iterator)
3420 28 : NULLIFY (basis_set_list_a, basis_set_list_b, basis_set_a, basis_set_b)
3421 :
3422 28 : CALL get_qs_env(qs_env, qs_kind_set=qs_kind_set, sab_orb=nl, natom=natom, para_env=para_env)
3423 :
3424 28 : nkind = SIZE(qs_kind_set)
3425 28 : CPASSERT(SIZE(nl) > 0)
3426 28 : CALL get_neighbor_list_set_p(neighbor_list_sets=nl, symmetric=do_symmetric)
3427 28 : CPASSERT(do_symmetric)
3428 216 : ALLOCATE (basis_set_list_a(nkind), basis_set_list_b(nkind))
3429 28 : CALL basis_set_list_setup(basis_set_list_a, "ORB", qs_kind_set)
3430 28 : CALL basis_set_list_setup(basis_set_list_b, "ORB", qs_kind_set)
3431 :
3432 28 : adjm_size = ((natom + 1)*natom)/2
3433 84 : ALLOCATE (interact_adjm(4*adjm_size))
3434 620 : interact_adjm = 0
3435 :
3436 28 : NULLIFY (nl_iterator)
3437 28 : CALL neighbor_list_iterator_create(nl_iterator, nl)
3438 2021 : DO WHILE (neighbor_list_iterate(nl_iterator) == 0)
3439 : CALL get_iterator_info(nl_iterator, &
3440 : ikind=ikind, jkind=jkind, &
3441 1993 : iatom=iatom, jatom=jatom)
3442 :
3443 1993 : basis_set_a => basis_set_list_a(ikind)%gto_basis_set
3444 1993 : IF (.NOT. ASSOCIATED(basis_set_a)) CYCLE
3445 1993 : basis_set_b => basis_set_list_b(jkind)%gto_basis_set
3446 1993 : IF (.NOT. ASSOCIATED(basis_set_b)) CYCLE
3447 :
3448 : ! move everything to the upper triangular part
3449 1993 : IF (iatom <= jatom) THEN
3450 : rowind = iatom
3451 : colind = jatom
3452 : ELSE
3453 670 : rowind = jatom
3454 670 : colind = iatom
3455 : ! swap the kinds too
3456 : ikind = ikind + jkind
3457 670 : jkind = ikind - jkind
3458 670 : ikind = ikind - jkind
3459 : END IF
3460 :
3461 : ! indexing upper triangular matrix
3462 1993 : ind = adjm_size - (natom - rowind + 1)*((natom - rowind + 1) + 1)/2 + colind - rowind + 1
3463 : ! convert the upper triangular matrix into a adjm_size x 4 matrix
3464 : ! columns are: iatom, jatom, ikind, jkind
3465 1993 : interact_adjm((ind - 1)*4 + 1) = rowind
3466 1993 : interact_adjm((ind - 1)*4 + 2) = colind
3467 1993 : interact_adjm((ind - 1)*4 + 3) = ikind
3468 1993 : interact_adjm((ind - 1)*4 + 4) = jkind
3469 : END DO
3470 :
3471 28 : CALL para_env%sum(interact_adjm)
3472 :
3473 : unit_nr = cp_print_key_unit_nr(logger, dft_section, "PRINT%ADJMAT_WRITE", &
3474 : extension=".adjmat", file_form="FORMATTED", &
3475 28 : file_status="REPLACE")
3476 28 : IF (unit_nr > 0) THEN
3477 14 : WRITE (unit_nr, "(1A,2X,1A,5X,1A,4X,A5,3X,A5)") "#", "iatom", "jatom", "ikind", "jkind"
3478 88 : DO k = 1, 4*adjm_size, 4
3479 : ! print only the interacting atoms
3480 88 : IF (interact_adjm(k) > 0 .AND. interact_adjm(k + 1) > 0) THEN
3481 74 : WRITE (unit_nr, "(I8,2X,I8,3X,I6,2X,I6)") interact_adjm(k:k + 3)
3482 : END IF
3483 : END DO
3484 : END IF
3485 :
3486 28 : CALL cp_print_key_finished_output(unit_nr, logger, dft_section, "PRINT%ADJMAT_WRITE")
3487 :
3488 28 : CALL neighbor_list_iterator_release(nl_iterator)
3489 56 : DEALLOCATE (basis_set_list_a, basis_set_list_b)
3490 : END IF
3491 :
3492 11305 : CALL timestop(handle)
3493 :
3494 22610 : END SUBROUTINE write_adjacency_matrix
3495 :
3496 : ! **************************************************************************************************
3497 : !> \brief Updates Hartree potential with MP2 density. Important for REPEAT charges
3498 : !> \param rho ...
3499 : !> \param qs_env ...
3500 : !> \author Vladimir Rybkin
3501 : ! **************************************************************************************************
3502 322 : SUBROUTINE update_hartree_with_mp2(rho, qs_env)
3503 : TYPE(qs_rho_type), POINTER :: rho
3504 : TYPE(qs_environment_type), POINTER :: qs_env
3505 :
3506 : LOGICAL :: use_virial
3507 : TYPE(pw_c1d_gs_type) :: rho_tot_gspace, v_hartree_gspace
3508 : TYPE(pw_c1d_gs_type), POINTER :: rho_core
3509 : TYPE(pw_env_type), POINTER :: pw_env
3510 : TYPE(pw_poisson_type), POINTER :: poisson_env
3511 : TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
3512 : TYPE(pw_r3d_rs_type), POINTER :: v_hartree_rspace
3513 : TYPE(qs_energy_type), POINTER :: energy
3514 : TYPE(virial_type), POINTER :: virial
3515 :
3516 322 : NULLIFY (auxbas_pw_pool, pw_env, poisson_env, energy, rho_core, v_hartree_rspace, virial)
3517 : CALL get_qs_env(qs_env, pw_env=pw_env, energy=energy, &
3518 : rho_core=rho_core, virial=virial, &
3519 322 : v_hartree_rspace=v_hartree_rspace)
3520 :
3521 322 : use_virial = virial%pv_availability .AND. (.NOT. virial%pv_numer)
3522 :
3523 : IF (.NOT. use_virial) THEN
3524 :
3525 : CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool, &
3526 268 : poisson_env=poisson_env)
3527 268 : CALL auxbas_pw_pool%create_pw(v_hartree_gspace)
3528 268 : CALL auxbas_pw_pool%create_pw(rho_tot_gspace)
3529 :
3530 268 : CALL calc_rho_tot_gspace(rho_tot_gspace, qs_env, rho)
3531 : CALL pw_poisson_solve(poisson_env, rho_tot_gspace, energy%hartree, &
3532 268 : v_hartree_gspace, rho_core=rho_core)
3533 :
3534 268 : CALL pw_transfer(v_hartree_gspace, v_hartree_rspace)
3535 268 : CALL pw_scale(v_hartree_rspace, v_hartree_rspace%pw_grid%dvol)
3536 :
3537 268 : CALL auxbas_pw_pool%give_back_pw(v_hartree_gspace)
3538 268 : CALL auxbas_pw_pool%give_back_pw(rho_tot_gspace)
3539 : END IF
3540 :
3541 322 : END SUBROUTINE update_hartree_with_mp2
3542 :
3543 : END MODULE qs_scf_post_gpw
|