(git:374b731)
Loading...
Searching...
No Matches
mixed_cdft_utils.F
Go to the documentation of this file.
1!--------------------------------------------------------------------------------------------------!
2! CP2K: A general program to perform molecular dynamics simulations !
3! Copyright 2000-2024 CP2K developers group <https://cp2k.org> !
4! !
5! SPDX-License-Identifier: GPL-2.0-or-later !
6!--------------------------------------------------------------------------------------------------!
7
8! **************************************************************************************************
9!> \brief Utility subroutines for mixed CDFT calculations
10!> \par History
11!> separated from mixed_cdft_methods [01.2017]
12!> \author Nico Holmberg [01.2017]
13! **************************************************************************************************
16 USE cell_types, ONLY: cell_type
25 USE cp_files, ONLY: open_file
45 USE cube_utils, ONLY: init_cube_info,&
48 USE dbcsr_api, ONLY: dbcsr_desymmetrize,&
49 dbcsr_get_info,&
50 dbcsr_init_p,&
51 dbcsr_p_type,&
52 dbcsr_release,&
53 dbcsr_release_p,&
54 dbcsr_type
76 USE kinds, ONLY: default_path_length,&
77 dp
88 USE pw_env_types, ONLY: pw_env_get,&
90 USE pw_grid_types, ONLY: halfspace,&
96 USE pw_pool_types, ONLY: pw_pool_create,&
111#include "./base/base_uses.f90"
112
113 IMPLICIT NONE
114 PRIVATE
115
116! *** Public subroutines ***
117
124
125 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'mixed_cdft_utils'
126
127CONTAINS
128
129! **************************************************************************************************
130!> \brief Parse settings for mixed cdft calculation and check their consistency
131!> \param force_env the force_env that holds the CDFT mixed_env
132!> \param mixed_env the mixed_env that holds the CDFT states
133!> \param mixed_cdft control section for mixed CDFT
134!> \param settings container for settings related to the mixed CDFT calculation
135!> \param natom the total number of atoms
136!> \par History
137!> 01.2017 created [Nico Holmberg]
138! **************************************************************************************************
139 SUBROUTINE mixed_cdft_parse_settings(force_env, mixed_env, mixed_cdft, &
140 settings, natom)
141 TYPE(force_env_type), POINTER :: force_env
142 TYPE(mixed_environment_type), POINTER :: mixed_env
143 TYPE(mixed_cdft_type), POINTER :: mixed_cdft
144 TYPE(mixed_cdft_settings_type) :: settings
145 INTEGER :: natom
146
147 INTEGER :: i, iatom, iforce_eval, igroup, &
148 nforce_eval, nkinds
149 INTEGER, ALLOCATABLE, DIMENSION(:, :) :: constraint_type
150 INTEGER, ALLOCATABLE, DIMENSION(:, :, :) :: array_sizes
151 LOGICAL :: is_match
152 TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
153 TYPE(cdft_control_type), POINTER :: cdft_control
154 TYPE(cp_1d_i_p_type), ALLOCATABLE, DIMENSION(:, :) :: atoms
155 TYPE(cp_1d_r_p_type), ALLOCATABLE, DIMENSION(:, :) :: coeff
156 TYPE(dft_control_type), POINTER :: dft_control
157 TYPE(force_env_type), POINTER :: force_env_qs
158 TYPE(pw_env_type), POINTER :: pw_env
159 TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
160 TYPE(qs_environment_type), POINTER :: qs_env
161
162 NULLIFY (dft_control, qs_env, pw_env, auxbas_pw_pool, force_env_qs, &
163 cdft_control)
164 ! Allocate storage for temporaries used for checking settings consistency
165 settings%max_nkinds = 30
166 nforce_eval = SIZE(force_env%sub_force_env)
167 ALLOCATE (settings%grid_span(nforce_eval))
168 ALLOCATE (settings%npts(3, nforce_eval))
169 ALLOCATE (settings%cutoff(nforce_eval))
170 ALLOCATE (settings%rel_cutoff(nforce_eval))
171 ALLOCATE (settings%spherical(nforce_eval))
172 ALLOCATE (settings%rs_dims(2, nforce_eval))
173 ALLOCATE (settings%odd(nforce_eval))
174 ALLOCATE (settings%atoms(natom, nforce_eval))
175 IF (mixed_cdft%run_type == mixed_cdft_parallel) THEN
176 ALLOCATE (settings%coeffs(natom, nforce_eval))
177 settings%coeffs = 0.0_dp
178 END IF
179 ! Some of the checked settings are only defined for certain types of constraints
180 ! We nonetheless use arrays that are large enough to contain settings for all constraints
181 ! This is not completely optimal...
182 ALLOCATE (settings%si(6, nforce_eval))
183 ALLOCATE (settings%sb(8, nforce_eval))
184 ALLOCATE (settings%sr(5, nforce_eval))
185 ALLOCATE (settings%cutoffs(settings%max_nkinds, nforce_eval))
186 ALLOCATE (settings%radii(settings%max_nkinds, nforce_eval))
187 settings%grid_span = 0
188 settings%npts = 0
189 settings%cutoff = 0.0_dp
190 settings%rel_cutoff = 0.0_dp
191 settings%spherical = 0
192 settings%is_spherical = .false.
193 settings%rs_dims = 0
194 settings%odd = 0
195 settings%is_odd = .false.
196 settings%atoms = 0
197 settings%si = 0
198 settings%sr = 0.0_dp
199 settings%sb = .false.
200 settings%cutoffs = 0.0_dp
201 settings%radii = 0.0_dp
202 ! Get information from the sub_force_envs
203 DO iforce_eval = 1, nforce_eval
204 IF (.NOT. ASSOCIATED(force_env%sub_force_env(iforce_eval)%force_env)) cycle
205 force_env_qs => force_env%sub_force_env(iforce_eval)%force_env
206 IF (mixed_env%do_mixed_qmmm_cdft) THEN
207 qs_env => force_env_qs%qmmm_env%qs_env
208 ELSE
209 CALL force_env_get(force_env_qs, qs_env=qs_env)
210 END IF
211 CALL get_qs_env(qs_env, pw_env=pw_env, dft_control=dft_control)
212 IF (.NOT. dft_control%qs_control%cdft) &
213 CALL cp_abort(__location__, &
214 "A mixed CDFT simulation with multiple force_evals was requested, "// &
215 "but CDFT constraints were not active in the QS section of all force_evals!")
216 cdft_control => dft_control%qs_control%cdft_control
217 CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool)
218 settings%bo = auxbas_pw_pool%pw_grid%bounds_local
219 ! Only the rank 0 process collects info about pw_grid and CDFT
220 IF (force_env_qs%para_env%is_source()) THEN
221 ! Grid settings
222 settings%grid_span(iforce_eval) = auxbas_pw_pool%pw_grid%grid_span
223 settings%npts(:, iforce_eval) = auxbas_pw_pool%pw_grid%npts
224 settings%cutoff(iforce_eval) = auxbas_pw_pool%pw_grid%cutoff
225 settings%rel_cutoff(iforce_eval) = dft_control%qs_control%relative_cutoff
226 IF (auxbas_pw_pool%pw_grid%spherical) settings%spherical(iforce_eval) = 1
227 settings%rs_dims(:, iforce_eval) = auxbas_pw_pool%pw_grid%para%rs_dims
228 IF (auxbas_pw_pool%pw_grid%grid_span == halfspace) settings%odd(iforce_eval) = 1
229 ! Becke constraint atoms/coeffs
230 IF (cdft_control%natoms .GT. SIZE(settings%atoms, 1)) &
231 CALL cp_abort(__location__, &
232 "More CDFT constraint atoms than defined in mixed section. "// &
233 "Use default values for MIXED\MAPPING.")
234 settings%atoms(1:cdft_control%natoms, iforce_eval) = cdft_control%atoms
235 IF (mixed_cdft%run_type == mixed_cdft_parallel) &
236 settings%coeffs(1:cdft_control%natoms, iforce_eval) = cdft_control%group(1)%coeff
237 ! Integer type settings
238 IF (cdft_control%type == outer_scf_becke_constraint) THEN
239 settings%si(1, iforce_eval) = cdft_control%becke_control%cutoff_type
240 settings%si(2, iforce_eval) = cdft_control%becke_control%cavity_shape
241 END IF
242 settings%si(3, iforce_eval) = dft_control%multiplicity
243 settings%si(4, iforce_eval) = SIZE(cdft_control%group)
244 settings%si(5, iforce_eval) = cdft_control%type
245 IF (cdft_control%type == outer_scf_hirshfeld_constraint) THEN
246 settings%si(6, iforce_eval) = cdft_control%hirshfeld_control%shape_function
247 settings%si(6, iforce_eval) = cdft_control%hirshfeld_control%gaussian_shape
248 END IF
249 ! Logicals
250 IF (cdft_control%type == outer_scf_becke_constraint) THEN
251 settings%sb(1, iforce_eval) = cdft_control%becke_control%cavity_confine
252 settings%sb(2, iforce_eval) = cdft_control%becke_control%should_skip
253 settings%sb(3, iforce_eval) = cdft_control%becke_control%print_cavity
254 settings%sb(4, iforce_eval) = cdft_control%becke_control%in_memory
255 settings%sb(5, iforce_eval) = cdft_control%becke_control%adjust
256 settings%sb(8, iforce_eval) = cdft_control%becke_control%use_bohr
257 END IF
258 IF (cdft_control%type == outer_scf_hirshfeld_constraint) THEN
259 settings%sb(8, iforce_eval) = cdft_control%hirshfeld_control%use_bohr
260 END IF
261 settings%sb(6, iforce_eval) = cdft_control%atomic_charges
262 settings%sb(7, iforce_eval) = qs_env%has_unit_metric
263 ! Reals
264 IF (cdft_control%type == outer_scf_becke_constraint) THEN
265 settings%sr(1, iforce_eval) = cdft_control%becke_control%rcavity
266 settings%sr(2, iforce_eval) = cdft_control%becke_control%rglobal
267 settings%sr(3, iforce_eval) = cdft_control%becke_control%eps_cavity
268 END IF
269 IF (cdft_control%type == outer_scf_hirshfeld_constraint) THEN
270 settings%sr(2, iforce_eval) = cdft_control%hirshfeld_control%radius
271 END IF
272 settings%sr(4, iforce_eval) = dft_control%qs_control%eps_rho_rspace
273 settings%sr(5, iforce_eval) = pw_env%cube_info(pw_env%auxbas_grid)%max_rad_ga
274 IF (cdft_control%type == outer_scf_becke_constraint) THEN
275 IF (cdft_control%becke_control%cutoff_type == becke_cutoff_element) THEN
276 nkinds = SIZE(cdft_control%becke_control%cutoffs_tmp)
277 IF (nkinds .GT. settings%max_nkinds) &
278 CALL cp_abort(__location__, &
279 "More than "//trim(cp_to_string(settings%max_nkinds))// &
280 " unique elements were defined in BECKE_CONSTRAINT\ELEMENT_CUTOFF. Are you sure"// &
281 " your input is correct? If yes, please increase max_nkinds and recompile.")
282 settings%cutoffs(1:nkinds, iforce_eval) = cdft_control%becke_control%cutoffs_tmp(:)
283 END IF
284 IF (cdft_control%becke_control%adjust) THEN
285 CALL get_qs_env(qs_env, atomic_kind_set=atomic_kind_set)
286 IF (.NOT. SIZE(atomic_kind_set) == SIZE(cdft_control%becke_control%radii_tmp)) &
287 CALL cp_abort(__location__, &
288 "Length of keyword BECKE_CONSTRAINT\ATOMIC_RADII does not "// &
289 "match number of atomic kinds in the input coordinate file.")
290 nkinds = SIZE(cdft_control%becke_control%radii_tmp)
291 IF (nkinds .GT. settings%max_nkinds) &
292 CALL cp_abort(__location__, &
293 "More than "//trim(cp_to_string(settings%max_nkinds))// &
294 " unique elements were defined in BECKE_CONSTRAINT\ATOMIC_RADII. Are you sure"// &
295 " your input is correct? If yes, please increase max_nkinds and recompile.")
296 settings%radii(1:nkinds, iforce_eval) = cdft_control%becke_control%radii_tmp(:)
297 END IF
298 END IF
299 IF (cdft_control%type == outer_scf_hirshfeld_constraint) THEN
300 IF (ASSOCIATED(cdft_control%hirshfeld_control%radii)) THEN
301 CALL get_qs_env(qs_env, atomic_kind_set=atomic_kind_set)
302 IF (.NOT. SIZE(atomic_kind_set) == SIZE(cdft_control%hirshfeld_control%radii)) &
303 CALL cp_abort(__location__, &
304 "Length of keyword HIRSHFELD_CONSTRAINT&RADII does not "// &
305 "match number of atomic kinds in the input coordinate file.")
306 nkinds = SIZE(cdft_control%hirshfeld_control%radii)
307 IF (nkinds .GT. settings%max_nkinds) &
308 CALL cp_abort(__location__, &
309 "More than "//trim(cp_to_string(settings%max_nkinds))// &
310 " unique elements were defined in HIRSHFELD_CONSTRAINT&RADII. Are you sure"// &
311 " your input is correct? If yes, please increase max_nkinds and recompile.")
312 settings%radii(1:nkinds, iforce_eval) = cdft_control%hirshfeld_control%radii(:)
313 END IF
314 END IF
315 END IF
316 END DO
317 ! Make sure the grids are consistent
318 CALL force_env%para_env%sum(settings%grid_span)
319 CALL force_env%para_env%sum(settings%npts)
320 CALL force_env%para_env%sum(settings%cutoff)
321 CALL force_env%para_env%sum(settings%rel_cutoff)
322 CALL force_env%para_env%sum(settings%spherical)
323 CALL force_env%para_env%sum(settings%rs_dims)
324 CALL force_env%para_env%sum(settings%odd)
325 is_match = .true.
326 DO iforce_eval = 2, nforce_eval
327 is_match = is_match .AND. (settings%grid_span(1) == settings%grid_span(iforce_eval))
328 is_match = is_match .AND. (settings%npts(1, 1) == settings%npts(1, iforce_eval))
329 is_match = is_match .AND. (settings%cutoff(1) == settings%cutoff(iforce_eval))
330 is_match = is_match .AND. (settings%rel_cutoff(1) == settings%rel_cutoff(iforce_eval))
331 is_match = is_match .AND. (settings%spherical(1) == settings%spherical(iforce_eval))
332 is_match = is_match .AND. (settings%rs_dims(1, 1) == settings%rs_dims(1, iforce_eval))
333 is_match = is_match .AND. (settings%rs_dims(2, 1) == settings%rs_dims(2, iforce_eval))
334 is_match = is_match .AND. (settings%odd(1) == settings%odd(iforce_eval))
335 END DO
336 IF (.NOT. is_match) &
337 CALL cp_abort(__location__, &
338 "Mismatch detected in the &MGRID settings of the CDFT force_evals.")
339 IF (settings%spherical(1) == 1) settings%is_spherical = .true.
340 IF (settings%odd(1) == 1) settings%is_odd = .true.
341 ! Make sure CDFT settings are consistent
342 CALL force_env%para_env%sum(settings%atoms)
343 IF (mixed_cdft%run_type == mixed_cdft_parallel) &
344 CALL force_env%para_env%sum(settings%coeffs)
345 settings%ncdft = 0
346 DO i = 1, SIZE(settings%atoms, 1)
347 DO iforce_eval = 2, nforce_eval
348 IF (mixed_cdft%run_type == mixed_cdft_parallel) THEN
349 IF (settings%atoms(i, 1) /= settings%atoms(i, iforce_eval)) is_match = .false.
350 IF (settings%coeffs(i, 1) /= settings%coeffs(i, iforce_eval)) is_match = .false.
351 END IF
352 END DO
353 IF (settings%atoms(i, 1) /= 0) settings%ncdft = settings%ncdft + 1
354 END DO
355 IF (.NOT. is_match .AND. mixed_cdft%run_type == mixed_cdft_parallel) &
356 CALL cp_abort(__location__, &
357 "Mismatch detected in the &CDFT section of the CDFT force_evals. "// &
358 "Parallel mode mixed CDFT requires identical constraint definitions in both CDFT states. "// &
359 "Switch to serial mode or disable keyword PARALLEL_BUILD if you "// &
360 "want to use nonidentical constraint definitions.")
361 CALL force_env%para_env%sum(settings%si)
362 CALL force_env%para_env%sum(settings%sr)
363 DO i = 1, SIZE(settings%sb, 1)
364 CALL force_env%para_env%sum(settings%sb(i, 1))
365 DO iforce_eval = 2, nforce_eval
366 CALL force_env%para_env%sum(settings%sb(i, iforce_eval))
367 IF (settings%sb(i, 1) .NEQV. settings%sb(i, iforce_eval)) is_match = .false.
368 END DO
369 END DO
370 DO i = 1, SIZE(settings%si, 1)
371 DO iforce_eval = 2, nforce_eval
372 IF (settings%si(i, 1) /= settings%si(i, iforce_eval)) is_match = .false.
373 END DO
374 END DO
375 DO i = 1, SIZE(settings%sr, 1)
376 DO iforce_eval = 2, nforce_eval
377 IF (settings%sr(i, 1) /= settings%sr(i, iforce_eval)) is_match = .false.
378 END DO
379 END DO
380 IF (.NOT. is_match) &
381 CALL cp_abort(__location__, &
382 "Mismatch detected in the &CDFT settings of the CDFT force_evals.")
383 ! Some CDFT features are currently disabled for mixed calculations: check that these features were not requested
384 IF (mixed_cdft%dlb .AND. .NOT. settings%sb(1, 1)) &
385 CALL cp_abort(__location__, &
386 "Parallel mode mixed CDFT load balancing requires Gaussian cavity confinement.")
387 ! Check for identical constraints in case of run type serial/parallel_nobuild
388 IF (mixed_cdft%run_type /= mixed_cdft_parallel) THEN
389 ! Get array sizes
390 ALLOCATE (array_sizes(nforce_eval, settings%si(4, 1), 2))
391 array_sizes(:, :, :) = 0
392 DO iforce_eval = 1, nforce_eval
393 IF (.NOT. ASSOCIATED(force_env%sub_force_env(iforce_eval)%force_env)) cycle
394 force_env_qs => force_env%sub_force_env(iforce_eval)%force_env
395 IF (mixed_env%do_mixed_qmmm_cdft) THEN
396 qs_env => force_env_qs%qmmm_env%qs_env
397 ELSE
398 CALL force_env_get(force_env_qs, qs_env=qs_env)
399 END IF
400 CALL get_qs_env(qs_env, dft_control=dft_control)
401 cdft_control => dft_control%qs_control%cdft_control
402 IF (force_env_qs%para_env%is_source()) THEN
403 DO igroup = 1, SIZE(cdft_control%group)
404 array_sizes(iforce_eval, igroup, 1) = SIZE(cdft_control%group(igroup)%atoms)
405 array_sizes(iforce_eval, igroup, 2) = SIZE(cdft_control%group(igroup)%coeff)
406 END DO
407 END IF
408 END DO
409 ! Sum up array sizes and check consistency
410 CALL force_env%para_env%sum(array_sizes)
411 IF (any(array_sizes(:, :, 1) /= array_sizes(1, 1, 1)) .OR. &
412 any(array_sizes(:, :, 2) /= array_sizes(1, 1, 2))) &
413 mixed_cdft%identical_constraints = .false.
414 ! Check constraint definitions
415 IF (mixed_cdft%identical_constraints) THEN
416 ! Prepare temporary storage
417 ALLOCATE (atoms(nforce_eval, settings%si(4, 1)))
418 ALLOCATE (coeff(nforce_eval, settings%si(4, 1)))
419 ALLOCATE (constraint_type(nforce_eval, settings%si(4, 1)))
420 constraint_type(:, :) = 0
421 DO iforce_eval = 1, nforce_eval
422 DO i = 1, settings%si(4, 1)
423 NULLIFY (atoms(iforce_eval, i)%array)
424 NULLIFY (coeff(iforce_eval, i)%array)
425 ALLOCATE (atoms(iforce_eval, i)%array(array_sizes(iforce_eval, i, 1)))
426 ALLOCATE (coeff(iforce_eval, i)%array(array_sizes(iforce_eval, i, 1)))
427 atoms(iforce_eval, i)%array(:) = 0
428 coeff(iforce_eval, i)%array(:) = 0
429 END DO
430 ! Get constraint definitions
431 IF (.NOT. ASSOCIATED(force_env%sub_force_env(iforce_eval)%force_env)) cycle
432 force_env_qs => force_env%sub_force_env(iforce_eval)%force_env
433 IF (mixed_env%do_mixed_qmmm_cdft) THEN
434 qs_env => force_env_qs%qmmm_env%qs_env
435 ELSE
436 CALL force_env_get(force_env_qs, qs_env=qs_env)
437 END IF
438 CALL get_qs_env(qs_env, dft_control=dft_control)
439 cdft_control => dft_control%qs_control%cdft_control
440 IF (force_env_qs%para_env%is_source()) THEN
441 DO i = 1, settings%si(4, 1)
442 atoms(iforce_eval, i)%array(:) = cdft_control%group(i)%atoms
443 coeff(iforce_eval, i)%array(:) = cdft_control%group(i)%coeff
444 constraint_type(iforce_eval, i) = cdft_control%group(i)%constraint_type
445 END DO
446 END IF
447 END DO
448 ! Sum up constraint definitions and check consistency
449 DO i = 1, settings%si(4, 1)
450 DO iforce_eval = 1, nforce_eval
451 CALL force_env%para_env%sum(atoms(iforce_eval, i)%array)
452 CALL force_env%para_env%sum(coeff(iforce_eval, i)%array)
453 CALL force_env%para_env%sum(constraint_type(iforce_eval, i))
454 END DO
455 DO iforce_eval = 2, nforce_eval
456 DO iatom = 1, SIZE(atoms(1, i)%array)
457 IF (atoms(1, i)%array(iatom) /= atoms(iforce_eval, i)%array(iatom)) &
458 mixed_cdft%identical_constraints = .false.
459 IF (coeff(1, i)%array(iatom) /= coeff(iforce_eval, i)%array(iatom)) &
460 mixed_cdft%identical_constraints = .false.
461 IF (.NOT. mixed_cdft%identical_constraints) EXIT
462 END DO
463 IF (constraint_type(1, i) /= constraint_type(iforce_eval, i)) &
464 mixed_cdft%identical_constraints = .false.
465 IF (.NOT. mixed_cdft%identical_constraints) EXIT
466 END DO
467 IF (.NOT. mixed_cdft%identical_constraints) EXIT
468 END DO
469 ! Deallocate temporary storage
470 DO iforce_eval = 1, nforce_eval
471 DO i = 1, settings%si(4, 1)
472 DEALLOCATE (atoms(iforce_eval, i)%array)
473 DEALLOCATE (coeff(iforce_eval, i)%array)
474 END DO
475 END DO
476 DEALLOCATE (atoms)
477 DEALLOCATE (coeff)
478 DEALLOCATE (constraint_type)
479 END IF
480 DEALLOCATE (array_sizes)
481 END IF
482 ! Deallocate some arrays that are no longer needed
483 IF (mixed_cdft%identical_constraints .AND. mixed_cdft%run_type /= mixed_cdft_parallel_nobuild) THEN
484 DO iforce_eval = 1, nforce_eval
485 IF (.NOT. ASSOCIATED(force_env%sub_force_env(iforce_eval)%force_env)) cycle
486 force_env_qs => force_env%sub_force_env(iforce_eval)%force_env
487 IF (mixed_env%do_mixed_qmmm_cdft) THEN
488 qs_env => force_env_qs%qmmm_env%qs_env
489 ELSE
490 CALL force_env_get(force_env_qs, qs_env=qs_env)
491 END IF
492 CALL get_qs_env(qs_env, dft_control=dft_control)
493 cdft_control => dft_control%qs_control%cdft_control
494 IF (mixed_cdft%run_type == mixed_cdft_parallel) THEN
495 IF (.NOT. dft_control%qs_control%gapw) THEN
496 DO i = 1, SIZE(cdft_control%group)
497 DEALLOCATE (cdft_control%group(i)%coeff)
498 DEALLOCATE (cdft_control%group(i)%atoms)
499 END DO
500 IF (.NOT. cdft_control%atomic_charges) DEALLOCATE (cdft_control%atoms)
501 END IF
502 ELSE IF (mixed_cdft%run_type == mixed_cdft_serial) THEN
503 IF (iforce_eval == 1) cycle
504 DO igroup = 1, SIZE(cdft_control%group)
505 IF (.NOT. dft_control%qs_control%gapw) THEN
506 DEALLOCATE (cdft_control%group(igroup)%coeff)
507 DEALLOCATE (cdft_control%group(igroup)%atoms)
508 END IF
509 END DO
510 IF (cdft_control%type == outer_scf_becke_constraint) THEN
511 IF (.NOT. cdft_control%atomic_charges) DEALLOCATE (cdft_control%atoms)
512 IF (cdft_control%becke_control%cavity_confine) &
513 CALL release_hirshfeld_type(cdft_control%becke_control%cavity_env)
514 IF (cdft_control%becke_control%cutoff_type == becke_cutoff_element) &
515 DEALLOCATE (cdft_control%becke_control%cutoffs_tmp)
516 IF (cdft_control%becke_control%adjust) &
517 DEALLOCATE (cdft_control%becke_control%radii_tmp)
518 END IF
519 END IF
520 END DO
521 END IF
522
523 END SUBROUTINE mixed_cdft_parse_settings
524
525! **************************************************************************************************
526!> \brief Transfer settings to mixed_cdft
527!> \param force_env the force_env that holds the CDFT states
528!> \param mixed_cdft the control section for mixed CDFT calculations
529!> \param settings container for settings related to the mixed CDFT calculation
530!> \par History
531!> 01.2017 created [Nico Holmberg]
532! **************************************************************************************************
533 SUBROUTINE mixed_cdft_transfer_settings(force_env, mixed_cdft, settings)
534 TYPE(force_env_type), POINTER :: force_env
535 TYPE(mixed_cdft_type), POINTER :: mixed_cdft
536 TYPE(mixed_cdft_settings_type) :: settings
537
538 INTEGER :: i, nkinds
539 LOGICAL :: is_match
540 TYPE(cdft_control_type), POINTER :: cdft_control
541
542 NULLIFY (cdft_control)
543 is_match = .true.
544 ! Transfer global settings
545 mixed_cdft%multiplicity = settings%si(3, 1)
546 mixed_cdft%has_unit_metric = settings%sb(7, 1)
547 mixed_cdft%eps_rho_rspace = settings%sr(4, 1)
548 mixed_cdft%nconstraint = settings%si(4, 1)
549 settings%radius = settings%sr(5, 1)
550 ! Transfer settings only needed if the constraint should be built in parallel
551 IF (mixed_cdft%run_type == mixed_cdft_parallel) THEN
552 IF (settings%sb(6, 1)) &
553 CALL cp_abort(__location__, &
554 "Calculation of atomic Becke charges not supported with parallel mode mixed CDFT")
555 IF (mixed_cdft%nconstraint /= 1) &
556 CALL cp_abort(__location__, &
557 "Parallel mode mixed CDFT does not yet support multiple constraints.")
558
559 IF (settings%si(5, 1) /= outer_scf_becke_constraint) &
560 CALL cp_abort(__location__, &
561 "Parallel mode mixed CDFT does not support Hirshfeld constraints.")
562
563 ALLOCATE (mixed_cdft%cdft_control)
564 CALL cdft_control_create(mixed_cdft%cdft_control)
565 cdft_control => mixed_cdft%cdft_control
566 ALLOCATE (cdft_control%atoms(settings%ncdft))
567 cdft_control%atoms = settings%atoms(1:settings%ncdft, 1)
568 ALLOCATE (cdft_control%group(1))
569 ALLOCATE (cdft_control%group(1)%atoms(settings%ncdft))
570 ALLOCATE (cdft_control%group(1)%coeff(settings%ncdft))
571 NULLIFY (cdft_control%group(1)%weight)
572 NULLIFY (cdft_control%group(1)%gradients)
573 NULLIFY (cdft_control%group(1)%integrated)
574 cdft_control%group(1)%atoms = cdft_control%atoms
575 cdft_control%group(1)%coeff = settings%coeffs(1:settings%ncdft, 1)
576 cdft_control%natoms = settings%ncdft
577 cdft_control%atomic_charges = settings%sb(6, 1)
578 cdft_control%becke_control%cutoff_type = settings%si(1, 1)
579 cdft_control%becke_control%cavity_confine = settings%sb(1, 1)
580 cdft_control%becke_control%should_skip = settings%sb(2, 1)
581 cdft_control%becke_control%print_cavity = settings%sb(3, 1)
582 cdft_control%becke_control%in_memory = settings%sb(4, 1)
583 cdft_control%becke_control%adjust = settings%sb(5, 1)
584 cdft_control%becke_control%cavity_shape = settings%si(2, 1)
585 cdft_control%becke_control%use_bohr = settings%sb(8, 1)
586 cdft_control%becke_control%rcavity = settings%sr(1, 1)
587 cdft_control%becke_control%rglobal = settings%sr(2, 1)
588 cdft_control%becke_control%eps_cavity = settings%sr(3, 1)
589 nkinds = 0
590 IF (cdft_control%becke_control%cutoff_type == becke_cutoff_element) THEN
591 CALL force_env%para_env%sum(settings%cutoffs)
592 DO i = 1, SIZE(settings%cutoffs, 1)
593 IF (settings%cutoffs(i, 1) /= settings%cutoffs(i, 2)) is_match = .false.
594 IF (settings%cutoffs(i, 1) /= 0.0_dp) nkinds = nkinds + 1
595 END DO
596 IF (.NOT. is_match) &
597 CALL cp_abort(__location__, &
598 "Mismatch detected in the &BECKE_CONSTRAINT "// &
599 "&ELEMENT_CUTOFF settings of the two force_evals.")
600 ALLOCATE (cdft_control%becke_control%cutoffs_tmp(nkinds))
601 cdft_control%becke_control%cutoffs_tmp = settings%cutoffs(1:nkinds, 1)
602 END IF
603 nkinds = 0
604 IF (cdft_control%becke_control%adjust) THEN
605 CALL force_env%para_env%sum(settings%radii)
606 DO i = 1, SIZE(settings%radii, 1)
607 IF (settings%radii(i, 1) /= settings%radii(i, 2)) is_match = .false.
608 IF (settings%radii(i, 1) /= 0.0_dp) nkinds = nkinds + 1
609 END DO
610 IF (.NOT. is_match) &
611 CALL cp_abort(__location__, &
612 "Mismatch detected in the &BECKE_CONSTRAINT "// &
613 "&ATOMIC_RADII settings of the two force_evals.")
614 ALLOCATE (cdft_control%becke_control%radii(nkinds))
615 cdft_control%becke_control%radii = settings%radii(1:nkinds, 1)
616 END IF
617 END IF
618
619 END SUBROUTINE mixed_cdft_transfer_settings
620
621! **************************************************************************************************
622!> \brief Initialize all the structures needed for a mixed CDFT calculation
623!> \param force_env the force_env that holds the CDFT mixed_env
624!> \param force_env_qs the force_env that holds the qs_env, which is CDFT state specific
625!> \param mixed_env the mixed_env that holds the CDFT states
626!> \param mixed_cdft the control section for mixed CDFT calculations
627!> \param settings container for settings related to the mixed CDFT calculation
628!> \par History
629!> 01.2017 created [Nico Holmberg]
630! **************************************************************************************************
631 SUBROUTINE mixed_cdft_init_structures(force_env, force_env_qs, mixed_env, mixed_cdft, settings)
632 TYPE(force_env_type), POINTER :: force_env, force_env_qs
633 TYPE(mixed_environment_type), POINTER :: mixed_env
634 TYPE(mixed_cdft_type), POINTER :: mixed_cdft
635 TYPE(mixed_cdft_settings_type) :: settings
636
637 CHARACTER(len=default_path_length) :: c_val, input_file_path, output_file_path
638 INTEGER :: i, imap, iounit, j, lp, n_force_eval, &
639 ncpu, nforce_eval, ntargets, offset, &
640 unit_nr
641 INTEGER, ALLOCATABLE, DIMENSION(:, :) :: bounds
642 INTEGER, DIMENSION(2, 3) :: bo, bo_mixed
643 INTEGER, DIMENSION(3) :: higher_grid_layout
644 INTEGER, DIMENSION(:), POINTER :: i_force_eval, mixed_rs_dims, recvbuffer, &
645 recvbuffer2, sendbuffer
646 LOGICAL :: is_match
647 TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
648 TYPE(cell_type), POINTER :: cell_mix
649 TYPE(cp_logger_type), POINTER :: logger
650 TYPE(cp_subsys_type), POINTER :: subsys_mix
651 TYPE(global_environment_type), POINTER :: globenv
652 TYPE(mp_request_type), DIMENSION(3) :: req
653 TYPE(pw_env_type), POINTER :: pw_env
654 TYPE(pw_grid_type), POINTER :: pw_grid
655 TYPE(pw_pool_p_type), DIMENSION(:), POINTER :: pw_pools
656 TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
657 TYPE(qs_environment_type), POINTER :: qs_env
658 TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
659 TYPE(realspace_grid_desc_p_type), DIMENSION(:), &
660 POINTER :: rs_descs
661 TYPE(realspace_grid_input_type) :: input_settings
662 TYPE(realspace_grid_type), DIMENSION(:), POINTER :: rs_grids
663 TYPE(section_vals_type), POINTER :: force_env_section, force_env_sections, kind_section, &
664 print_section, root_section, rs_grid_section, subsys_section
665
666 NULLIFY (cell_mix, subsys_mix, force_env_section, subsys_section, &
667 print_section, root_section, kind_section, force_env_sections, &
668 rs_grid_section, auxbas_pw_pool, pw_env, pw_pools, pw_grid, &
669 sendbuffer, qs_env, mixed_rs_dims, i_force_eval, recvbuffer, &
670 recvbuffer2, globenv, atomic_kind_set, qs_kind_set, rs_descs, &
671 rs_grids)
672
673 logger => cp_get_default_logger()
674 CALL force_env_get(force_env=force_env, force_env_section=force_env_section)
675 print_section => section_vals_get_subs_vals(force_env_section, "MIXED%MIXED_CDFT%PRINT%PROGRAM_RUN_INFO")
676 iounit = cp_print_key_unit_nr(logger, print_section, '', extension='.mixedLog')
677 is_match = .true.
678 nforce_eval = SIZE(force_env%sub_force_env)
679 ncpu = force_env%para_env%num_pe
680 ! Get infos about the mixed subsys
681 IF (.NOT. mixed_env%do_mixed_qmmm_cdft) THEN
682 CALL force_env_get(force_env=force_env, &
683 subsys=subsys_mix)
684 ELSE
685 CALL get_qs_env(force_env_qs%qmmm_env%qs_env, &
686 cp_subsys=subsys_mix)
687 END IF
688 ! Init structures only needed when the CDFT states are treated in parallel
689 IF (mixed_cdft%run_type == mixed_cdft_parallel) THEN
690 ! Start building the mixed auxbas_pw_pool
691 CALL pw_grid_create(pw_grid, force_env%para_env)
692 CALL pw_env_create(mixed_cdft%pw_env)
693 ! Decide what kind of layout to use and setup the grid
694 ! Processor mappings currently supported:
695 ! (2np,1) --> (np,1)
696 ! (nx,2ny) --> (nx,ny)
697 ! (nx,ny) --> (nx*ny/2,1) (required when xc_smooth is in use and with intermediate proc counts)
698 !
699 ! For cases 2 and 3, dlb redistributes YZ slices from overloaded processors to underloaded processors
700 ! For case 1, XZ slices are redistributed
701 ! TODO: Unify mappings. Now we essentially have separate code for cases 1-2 and 3.
702 ! This leads to very messy code especially with dlb turned on...
703 ! In terms of memory usage, it would be beneficial to replace case 1 with 3
704 ! and implement a similar arbitrary mapping to replace case 2
705
706 mixed_cdft%is_pencil = .false. ! Flag to control the first two mappings
707 mixed_cdft%is_special = .false. ! Flag to control the last mapping
708 ! With xc smoothing, the grid is always (ncpu/2,1) distributed
709 ! and correct behavior cannot be guaranteed for ncpu/2 > nx, so we abort...
710 IF (ncpu/2 .GT. settings%npts(1, 1)) &
711 cpabort("ncpu/2 => nx: decrease ncpu or disable xc_smoothing")
712 !
713 ALLOCATE (mixed_rs_dims(2))
714 IF (settings%rs_dims(2, 1) /= 1) mixed_cdft%is_pencil = .true.
715 IF (.NOT. mixed_cdft%is_pencil .AND. ncpu .GT. settings%npts(1, 1)) mixed_cdft%is_special = .true.
716 IF (mixed_cdft%is_special) THEN
717 mixed_rs_dims = (/-1, -1/)
718 ELSE IF (mixed_cdft%is_pencil) THEN
719 mixed_rs_dims = (/settings%rs_dims(1, 1), 2*settings%rs_dims(2, 1)/)
720 ELSE
721 mixed_rs_dims = (/2*settings%rs_dims(1, 1), 1/)
722 END IF
723 IF (.NOT. mixed_env%do_mixed_qmmm_cdft) THEN
724 CALL force_env_get(force_env=force_env, &
725 cell=cell_mix)
726 ELSE
727 CALL get_qs_env(force_env_qs%qmmm_env%qs_env, &
728 cell=cell_mix)
729 END IF
730 CALL pw_grid_setup(cell_mix%hmat, pw_grid, grid_span=settings%grid_span(1), &
731 npts=settings%npts(:, 1), cutoff=settings%cutoff(1), &
732 spherical=settings%is_spherical, odd=settings%is_odd, &
733 fft_usage=.true., ncommensurate=0, icommensurate=1, &
734 blocked=do_pw_grid_blocked_false, rs_dims=mixed_rs_dims, &
735 iounit=iounit)
736 ! Check if the layout was successfully created
737 IF (mixed_cdft%is_special) THEN
738 IF (.NOT. pw_grid%para%rs_dims(2) /= 1) is_match = .false.
739 ELSE IF (mixed_cdft%is_pencil) THEN
740 IF (.NOT. pw_grid%para%rs_dims(1) == mixed_rs_dims(1)) is_match = .false.
741 ELSE
742 IF (.NOT. pw_grid%para%rs_dims(2) == 1) is_match = .false.
743 END IF
744 IF (.NOT. is_match) &
745 CALL cp_abort(__location__, &
746 "Unable to create a suitable grid distribution "// &
747 "for mixed CDFT calculations. Try decreasing the total number "// &
748 "of processors or disabling xc_smoothing.")
749 DEALLOCATE (mixed_rs_dims)
750 ! Create the pool
751 bo_mixed = pw_grid%bounds_local
752 ALLOCATE (pw_pools(1))
753 NULLIFY (pw_pools(1)%pool)
754 CALL pw_pool_create(pw_pools(1)%pool, pw_grid=pw_grid)
755 ! Initialize Gaussian cavity confinement
756 IF (mixed_cdft%cdft_control%becke_control%cavity_confine) THEN
757 CALL create_hirshfeld_type(mixed_cdft%cdft_control%becke_control%cavity_env)
758 CALL set_hirshfeld_info(mixed_cdft%cdft_control%becke_control%cavity_env, &
759 shape_function_type=shape_function_gaussian, iterative=.false., &
760 radius_type=mixed_cdft%cdft_control%becke_control%cavity_shape, &
761 use_bohr=mixed_cdft%cdft_control%becke_control%use_bohr)
762 END IF
763 ! Gaussian confinement/wavefunction overlap method needs qs_kind_set
764 ! Gaussian cavity confinement also needs the auxbas_rs_grid
765 IF (mixed_cdft%cdft_control%becke_control%cavity_confine .OR. &
766 mixed_cdft%wfn_overlap_method) THEN
767 print_section => section_vals_get_subs_vals(force_env_section, &
768 "PRINT%GRID_INFORMATION")
769 ALLOCATE (mixed_cdft%pw_env%gridlevel_info)
770 CALL init_gaussian_gridlevel(mixed_cdft%pw_env%gridlevel_info, &
771 ngrid_levels=1, cutoff=settings%cutoff, &
772 rel_cutoff=settings%rel_cutoff(1), &
773 print_section=print_section)
774 ALLOCATE (rs_descs(1))
775 ALLOCATE (rs_grids(1))
776 ALLOCATE (mixed_cdft%pw_env%cube_info(1))
777 higher_grid_layout = (/-1, -1, -1/)
779 CALL init_cube_info(mixed_cdft%pw_env%cube_info(1), &
780 pw_grid%dr(:), pw_grid%dh(:, :), &
781 pw_grid%dh_inv(:, :), &
782 pw_grid%orthorhombic, settings%radius)
783 NULLIFY (root_section, force_env_section, force_env_sections, rs_grid_section)
784 CALL force_env_get(force_env, root_section=root_section)
785 force_env_sections => section_vals_get_subs_vals(root_section, "FORCE_EVAL")
786 CALL multiple_fe_list(force_env_sections, root_section, i_force_eval, n_force_eval)
787 CALL section_vals_duplicate(force_env_sections, force_env_section, &
788 i_force_eval(2), i_force_eval(2))
789 rs_grid_section => section_vals_get_subs_vals(force_env_section, "DFT%MGRID%RS_GRID")
790 CALL init_input_type(input_settings, &
791 nsmax=2*max(1, return_cube_max_iradius(mixed_cdft%pw_env%cube_info(1))) + 1, &
792 rs_grid_section=rs_grid_section, ilevel=1, &
793 higher_grid_layout=higher_grid_layout)
794 NULLIFY (rs_descs(1)%rs_desc)
795 CALL rs_grid_create_descriptor(rs_descs(1)%rs_desc, pw_grid, input_settings)
796 IF (rs_descs(1)%rs_desc%distributed) higher_grid_layout = rs_descs(1)%rs_desc%group_dim
797 CALL rs_grid_create(rs_grids(1), rs_descs(1)%rs_desc)
798 CALL rs_grid_print(rs_grids(1), iounit)
799 mixed_cdft%pw_env%rs_descs => rs_descs
800 mixed_cdft%pw_env%rs_grids => rs_grids
801 ! qs_kind_set
802 subsys_section => section_vals_get_subs_vals(force_env_sections, "SUBSYS", &
803 i_rep_section=i_force_eval(1))
804 kind_section => section_vals_get_subs_vals(subsys_section, "KIND")
805 NULLIFY (qs_kind_set)
806 CALL cp_subsys_get(subsys_mix, atomic_kind_set=atomic_kind_set)
807 CALL create_qs_kind_set(qs_kind_set, atomic_kind_set, kind_section, &
808 force_env%para_env, force_env_section)
809 mixed_cdft%qs_kind_set => qs_kind_set
810 DEALLOCATE (i_force_eval)
811 CALL section_vals_release(force_env_section)
812 END IF
813 CALL force_env_get(force_env=force_env, &
814 force_env_section=force_env_section)
815 CALL pw_grid_release(pw_grid)
816 mixed_cdft%pw_env%auxbas_grid = 1
817 NULLIFY (mixed_cdft%pw_env%pw_pools)
818 mixed_cdft%pw_env%pw_pools => pw_pools
819 bo = settings%bo
820 ! Determine which processors need to exchange data when redistributing the weight/gradient
821 IF (.NOT. mixed_cdft%is_special) THEN
822 ALLOCATE (mixed_cdft%dest_list(2))
823 ALLOCATE (mixed_cdft%source_list(2))
824 imap = force_env%para_env%mepos/2
825 mixed_cdft%dest_list = (/imap, imap + force_env%para_env%num_pe/2/)
826 imap = mod(force_env%para_env%mepos, force_env%para_env%num_pe/2) + &
827 modulo(force_env%para_env%mepos, force_env%para_env%num_pe/2)
828 mixed_cdft%source_list = (/imap, imap + 1/)
829 ! Determine bounds of the data that is replicated
830 ALLOCATE (mixed_cdft%recv_bo(4))
831 ALLOCATE (sendbuffer(2), recvbuffer(2), recvbuffer2(2))
832 IF (mixed_cdft%is_pencil) THEN
833 sendbuffer = (/bo_mixed(1, 2), bo_mixed(2, 2)/)
834 ELSE
835 sendbuffer = (/bo_mixed(1, 1), bo_mixed(2, 1)/)
836 END IF
837 ! Communicate bounds in steps
838 CALL force_env%para_env%isend(msgin=sendbuffer, dest=mixed_cdft%dest_list(1), &
839 request=req(1))
840 CALL force_env%para_env%irecv(msgout=recvbuffer, source=mixed_cdft%source_list(1), &
841 request=req(2))
842 CALL force_env%para_env%irecv(msgout=recvbuffer2, source=mixed_cdft%source_list(2), &
843 request=req(3))
844 CALL req(1)%wait()
845 CALL force_env%para_env%isend(msgin=sendbuffer, dest=mixed_cdft%dest_list(2), &
846 request=req(1))
847 CALL mp_waitall(req)
848 mixed_cdft%recv_bo(1:2) = recvbuffer
849 mixed_cdft%recv_bo(3:4) = recvbuffer2
850 DEALLOCATE (sendbuffer, recvbuffer, recvbuffer2)
851 ELSE
852 IF (mixed_env%do_mixed_qmmm_cdft) THEN
853 qs_env => force_env_qs%qmmm_env%qs_env
854 ELSE
855 CALL force_env_get(force_env_qs, qs_env=qs_env)
856 END IF
857 CALL get_qs_env(qs_env, pw_env=pw_env)
858 CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool)
859 ! work out the pw grid points each proc holds in the two (identical) parallel proc groups
860 ! note we only care about the x dir since we assume the y dir is not subdivided
861 ALLOCATE (bounds(0:auxbas_pw_pool%pw_grid%para%group_size - 1, 1:2))
862 DO i = 0, auxbas_pw_pool%pw_grid%para%group_size - 1
863 bounds(i, 1:2) = auxbas_pw_pool%pw_grid%para%bo(1:2, 1, i, 1)
864 bounds(i, 1:2) = bounds(i, 1:2) - auxbas_pw_pool%pw_grid%npts(1)/2 - 1
865 END DO
866 ! work out which procs to send my grid points
867 ! first get the number of target procs per group
868 ntargets = 0
869 offset = -1
870 DO i = 0, auxbas_pw_pool%pw_grid%para%group_size - 1
871 IF ((bounds(i, 1) .GE. bo_mixed(1, 1) .AND. bounds(i, 1) .LE. bo_mixed(2, 1)) .OR. &
872 (bounds(i, 2) .GE. bo_mixed(1, 1) .AND. bounds(i, 2) .LE. bo_mixed(2, 1))) THEN
873 ntargets = ntargets + 1
874 IF (offset == -1) offset = i
875 ELSE IF (bounds(i, 2) .GT. bo_mixed(2, 1)) THEN
876 EXIT
877 ELSE
878 cycle
879 END IF
880 END DO
881 ALLOCATE (mixed_cdft%dest_list(ntargets))
882 ALLOCATE (mixed_cdft%dest_list_bo(2, ntargets))
883 ! now determine the actual grid points to send
884 j = 1
885 DO i = offset, offset + ntargets - 1
886 mixed_cdft%dest_list(j) = i
887 mixed_cdft%dest_list_bo(:, j) = (/bo_mixed(1, 1) + (bounds(i, 1) - bo_mixed(1, 1)), &
888 bo_mixed(2, 1) + (bounds(i, 2) - bo_mixed(2, 1))/)
889 j = j + 1
890 END DO
891 ALLOCATE (mixed_cdft%dest_list_save(ntargets), mixed_cdft%dest_bo_save(2, ntargets))
892 ! We need to store backups of these arrays since they might get reallocated during dlb
893 mixed_cdft%dest_list_save = mixed_cdft%dest_list
894 mixed_cdft%dest_bo_save = mixed_cdft%dest_list_bo
895 ! finally determine which procs will send me grid points
896 ! now we need info about y dir also
897 DEALLOCATE (bounds)
898 ALLOCATE (bounds(0:pw_pools(1)%pool%pw_grid%para%group_size - 1, 1:4))
899 DO i = 0, pw_pools(1)%pool%pw_grid%para%group_size - 1
900 bounds(i, 1:2) = pw_pools(1)%pool%pw_grid%para%bo(1:2, 1, i, 1)
901 bounds(i, 3:4) = pw_pools(1)%pool%pw_grid%para%bo(1:2, 2, i, 1)
902 bounds(i, 1:2) = bounds(i, 1:2) - pw_pools(1)%pool%pw_grid%npts(1)/2 - 1
903 bounds(i, 3:4) = bounds(i, 3:4) - pw_pools(1)%pool%pw_grid%npts(2)/2 - 1
904 END DO
905 ntargets = 0
906 offset = -1
907 DO i = 0, pw_pools(1)%pool%pw_grid%para%group_size - 1
908 IF ((bo(1, 1) .GE. bounds(i, 1) .AND. bo(1, 1) .LE. bounds(i, 2)) .OR. &
909 (bo(2, 1) .GE. bounds(i, 1) .AND. bo(2, 1) .LE. bounds(i, 2))) THEN
910 ntargets = ntargets + 1
911 IF (offset == -1) offset = i
912 ELSE IF (bo(2, 1) .LT. bounds(i, 1)) THEN
913 EXIT
914 ELSE
915 cycle
916 END IF
917 END DO
918 ALLOCATE (mixed_cdft%source_list(ntargets))
919 ALLOCATE (mixed_cdft%source_list_bo(4, ntargets))
920 j = 1
921 DO i = offset, offset + ntargets - 1
922 mixed_cdft%source_list(j) = i
923 IF (bo(1, 1) .GE. bounds(i, 1) .AND. bo(2, 1) .LE. bounds(i, 2)) THEN
924 mixed_cdft%source_list_bo(:, j) = (/bo(1, 1), bo(2, 1), &
925 bounds(i, 3), bounds(i, 4)/)
926 ELSE IF (bo(1, 1) .GE. bounds(i, 1) .AND. bo(1, 1) .LE. bounds(i, 2)) THEN
927 mixed_cdft%source_list_bo(:, j) = (/bo(1, 1), bounds(i, 2), &
928 bounds(i, 3), bounds(i, 4)/)
929 ELSE
930 mixed_cdft%source_list_bo(:, j) = (/bounds(i, 1), bo(2, 1), &
931 bounds(i, 3), bounds(i, 4)/)
932 END IF
933 j = j + 1
934 END DO
935 ALLOCATE (mixed_cdft%source_list_save(ntargets), mixed_cdft%source_bo_save(4, ntargets))
936 ! We need to store backups of these arrays since they might get reallocated during dlb
937 mixed_cdft%source_list_save = mixed_cdft%source_list
938 mixed_cdft%source_bo_save = mixed_cdft%source_list_bo
939 DEALLOCATE (bounds)
940 END IF
941 ELSE
942 ! Create loggers to redirect the output of all CDFT states to different files
943 ! even when the states are treated in serial (the initial print of QS data [basis set etc] for
944 ! all states unfortunately goes to the first log file)
945 CALL force_env_get(force_env, root_section=root_section)
946 ALLOCATE (mixed_cdft%sub_logger(nforce_eval - 1))
947 DO i = 1, nforce_eval - 1
948 IF (force_env%para_env%is_source()) THEN
949 CALL section_vals_val_get(root_section, "GLOBAL%PROJECT_NAME", &
950 c_val=input_file_path)
951 lp = len_trim(input_file_path)
952 input_file_path(lp + 1:len(input_file_path)) = "-r-"//adjustl(cp_to_string(i + 1))
953 lp = len_trim(input_file_path)
954 output_file_path = input_file_path(1:lp)//".out"
955 CALL open_file(file_name=output_file_path, file_status="UNKNOWN", &
956 file_action="WRITE", file_position="APPEND", &
957 unit_number=unit_nr)
958 ELSE
959 unit_nr = -1
960 END IF
961 CALL cp_logger_create(mixed_cdft%sub_logger(i)%p, &
962 para_env=force_env%para_env, &
963 default_global_unit_nr=unit_nr, &
964 close_global_unit_on_dealloc=.false.)
965 ! Try to use better names for the local log if it is not too late
966 CALL section_vals_val_get(root_section, "GLOBAL%OUTPUT_FILE_NAME", &
967 c_val=c_val)
968 IF (c_val /= "") THEN
969 CALL cp_logger_set(mixed_cdft%sub_logger(i)%p, &
970 local_filename=trim(c_val)//"_localLog")
971 END IF
972 CALL section_vals_val_get(root_section, "GLOBAL%PROJECT", c_val=c_val)
973 IF (c_val /= "") THEN
974 CALL cp_logger_set(mixed_cdft%sub_logger(i)%p, &
975 local_filename=trim(c_val)//"_localLog")
976 END IF
977 mixed_cdft%sub_logger(i)%p%iter_info%project_name = c_val
978 CALL section_vals_val_get(root_section, "GLOBAL%PRINT_LEVEL", &
979 i_val=mixed_cdft%sub_logger(i)%p%iter_info%print_level)
980 END DO
981 IF (mixed_cdft%wfn_overlap_method) THEN
982 ! qs_kind_set
983 NULLIFY (root_section, force_env_section, force_env_sections, rs_grid_section)
984 CALL force_env_get(force_env, root_section=root_section)
985 force_env_sections => section_vals_get_subs_vals(root_section, "FORCE_EVAL")
986 CALL multiple_fe_list(force_env_sections, root_section, i_force_eval, n_force_eval)
987 CALL section_vals_duplicate(force_env_sections, force_env_section, &
988 i_force_eval(2), i_force_eval(2))
989 subsys_section => section_vals_get_subs_vals(force_env_sections, "SUBSYS", &
990 i_rep_section=i_force_eval(1))
991 kind_section => section_vals_get_subs_vals(subsys_section, "KIND")
992 NULLIFY (qs_kind_set)
993 CALL cp_subsys_get(subsys_mix, atomic_kind_set=atomic_kind_set)
994 CALL create_qs_kind_set(qs_kind_set, atomic_kind_set, kind_section, &
995 force_env%para_env, force_env_section)
996 mixed_cdft%qs_kind_set => qs_kind_set
997 DEALLOCATE (i_force_eval)
998 CALL section_vals_release(force_env_section)
999 mixed_cdft%qs_kind_set => qs_kind_set
1000 END IF
1001 CALL force_env_get(force_env=force_env, &
1002 force_env_section=force_env_section)
1003 END IF
1004 ! Deallocate settings temporaries
1005 DEALLOCATE (settings%grid_span)
1006 DEALLOCATE (settings%npts)
1007 DEALLOCATE (settings%spherical)
1008 DEALLOCATE (settings%rs_dims)
1009 DEALLOCATE (settings%odd)
1010 DEALLOCATE (settings%atoms)
1011 IF (mixed_cdft%run_type == mixed_cdft_parallel) &
1012 DEALLOCATE (settings%coeffs)
1013 DEALLOCATE (settings%cutoffs)
1014 DEALLOCATE (settings%radii)
1015 DEALLOCATE (settings%si)
1016 DEALLOCATE (settings%sr)
1017 DEALLOCATE (settings%sb)
1018 DEALLOCATE (settings%cutoff)
1019 DEALLOCATE (settings%rel_cutoff)
1020 ! Setup mixed blacs_env for redistributing arrays during ET coupling calculation
1021 IF (mixed_env%do_mixed_et) THEN
1022 NULLIFY (root_section)
1023 CALL force_env_get(force_env, globenv=globenv, root_section=root_section)
1024 CALL cp_blacs_env_create(mixed_cdft%blacs_env, force_env%para_env, globenv%blacs_grid_layout, &
1025 globenv%blacs_repeatable)
1026 END IF
1027 CALL cp_print_key_finished_output(iounit, logger, force_env_section, &
1028 "MIXED%MIXED_CDFT%PRINT%PROGRAM_RUN_INFO")
1029
1030 END SUBROUTINE mixed_cdft_init_structures
1031
1032! **************************************************************************************************
1033!> \brief Redistribute arrays needed for an ET coupling calculation from individual CDFT states to
1034!> the mixed CDFT env, that is, move the arrays to the correct blacs context. For parallel
1035!> simulations, the array processor distributions also change from N to 2N processors.
1036!> \param force_env the force_env that holds the CDFT states
1037!> \par History
1038!> 01.2017 created [Nico Holmberg]
1039! **************************************************************************************************
1041 TYPE(force_env_type), POINTER :: force_env
1042
1043 INTEGER :: iforce_eval, ispin, ivar, ncol_overlap, &
1044 ncol_wmat, nforce_eval, nrow_overlap, &
1045 nrow_wmat, nspins, nvar
1046 INTEGER, ALLOCATABLE, DIMENSION(:) :: ncol_mo, nrow_mo
1047 LOGICAL :: uniform_occupation
1048 LOGICAL, ALLOCATABLE, DIMENSION(:) :: has_occupation_numbers
1049 TYPE(cp_1d_r_p_type), ALLOCATABLE, DIMENSION(:, :) :: occno_tmp
1050 TYPE(cp_blacs_env_type), POINTER :: blacs_env
1051 TYPE(cp_fm_struct_type), POINTER :: fm_struct_mo, fm_struct_overlap, &
1052 fm_struct_tmp, fm_struct_wmat
1053 TYPE(cp_fm_type) :: matrix_s_tmp, mixed_matrix_s_tmp
1054 TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:, :) :: matrix_p_tmp, mixed_matrix_p_tmp, &
1055 mixed_wmat_tmp, mo_coeff_tmp, wmat_tmp
1056 TYPE(cp_fm_type), DIMENSION(:, :), POINTER :: mixed_mo_coeff
1057 TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: density_matrix, w_matrix
1058 TYPE(dbcsr_type) :: desymm_tmp
1059 TYPE(dbcsr_type), POINTER :: mixed_matrix_s
1060 TYPE(dft_control_type), POINTER :: dft_control
1061 TYPE(force_env_type), POINTER :: force_env_qs
1062 TYPE(mixed_cdft_type), POINTER :: mixed_cdft
1063 TYPE(mixed_environment_type), POINTER :: mixed_env
1064 TYPE(qs_environment_type), POINTER :: qs_env
1065
1066 NULLIFY (mixed_env, mixed_cdft, qs_env, dft_control, fm_struct_mo, &
1067 fm_struct_wmat, fm_struct_overlap, fm_struct_tmp, &
1068 mixed_mo_coeff, mixed_matrix_s, density_matrix, blacs_env, w_matrix, force_env_qs)
1069 cpassert(ASSOCIATED(force_env))
1070 mixed_env => force_env%mixed_env
1071 nforce_eval = SIZE(force_env%sub_force_env)
1072 CALL get_mixed_env(mixed_env, cdft_control=mixed_cdft)
1073 cpassert(ASSOCIATED(mixed_cdft))
1074 CALL mixed_cdft_work_type_init(mixed_cdft%matrix)
1075 ! Get nspins and query for non-uniform occupation numbers
1076 ALLOCATE (has_occupation_numbers(nforce_eval))
1077 has_occupation_numbers = .false.
1078 DO iforce_eval = 1, nforce_eval
1079 IF (.NOT. ASSOCIATED(force_env%sub_force_env(iforce_eval)%force_env)) cycle
1080 force_env_qs => force_env%sub_force_env(iforce_eval)%force_env
1081 IF (force_env%mixed_env%do_mixed_qmmm_cdft) THEN
1082 qs_env => force_env_qs%qmmm_env%qs_env
1083 ELSE
1084 CALL force_env_get(force_env_qs, qs_env=qs_env)
1085 END IF
1086 CALL get_qs_env(qs_env, dft_control=dft_control)
1087 cpassert(ASSOCIATED(dft_control))
1088 nspins = dft_control%nspins
1089 IF (force_env_qs%para_env%is_source()) &
1090 has_occupation_numbers(iforce_eval) = ALLOCATED(dft_control%qs_control%cdft_control%occupations)
1091 END DO
1092 CALL force_env%para_env%sum(has_occupation_numbers(1))
1093 DO iforce_eval = 2, nforce_eval
1094 CALL force_env%para_env%sum(has_occupation_numbers(iforce_eval))
1095 IF (has_occupation_numbers(1) .NEQV. has_occupation_numbers(iforce_eval)) &
1096 CALL cp_abort(__location__, &
1097 "Mixing of uniform and non-uniform occupations is not allowed.")
1098 END DO
1099 uniform_occupation = .NOT. has_occupation_numbers(1)
1100 DEALLOCATE (has_occupation_numbers)
1101 ! Get number of weight functions per state as well as the type of each constraint
1102 nvar = SIZE(dft_control%qs_control%cdft_control%target)
1103 IF (.NOT. ALLOCATED(mixed_cdft%constraint_type)) THEN
1104 ALLOCATE (mixed_cdft%constraint_type(nvar, nforce_eval))
1105 mixed_cdft%constraint_type(:, :) = 0
1106 IF (mixed_cdft%identical_constraints) THEN
1107 DO ivar = 1, nvar
1108 mixed_cdft%constraint_type(ivar, :) = &
1109 dft_control%qs_control%cdft_control%group(ivar)%constraint_type
1110 END DO
1111 ELSE
1112 ! Possibly couple spin and charge constraints
1113 DO iforce_eval = 1, nforce_eval
1114 IF (.NOT. ASSOCIATED(force_env%sub_force_env(iforce_eval)%force_env)) cycle
1115 IF (force_env%mixed_env%do_mixed_qmmm_cdft) THEN
1116 qs_env => force_env%sub_force_env(iforce_eval)%force_env%qmmm_env%qs_env
1117 ELSE
1118 CALL force_env_get(force_env%sub_force_env(iforce_eval)%force_env, qs_env=qs_env)
1119 END IF
1120 CALL get_qs_env(qs_env, dft_control=dft_control)
1121 IF (force_env%sub_force_env(iforce_eval)%force_env%para_env%is_source()) THEN
1122 DO ivar = 1, nvar
1123 mixed_cdft%constraint_type(ivar, iforce_eval) = &
1124 dft_control%qs_control%cdft_control%group(ivar)%constraint_type
1125 END DO
1126 END IF
1127 END DO
1128 CALL force_env%para_env%sum(mixed_cdft%constraint_type)
1129 END IF
1130 END IF
1131 ! Transfer data from sub_force_envs to temporaries
1132 ALLOCATE (mixed_cdft%matrix%mixed_mo_coeff(nforce_eval, nspins))
1133 mixed_mo_coeff => mixed_cdft%matrix%mixed_mo_coeff
1134 ALLOCATE (mixed_cdft%matrix%w_matrix(nforce_eval, nvar))
1135 w_matrix => mixed_cdft%matrix%w_matrix
1136 CALL dbcsr_init_p(mixed_cdft%matrix%mixed_matrix_s)
1137 mixed_matrix_s => mixed_cdft%matrix%mixed_matrix_s
1138 IF (mixed_cdft%calculate_metric) THEN
1139 ALLOCATE (mixed_cdft%matrix%density_matrix(nforce_eval, nspins))
1140 density_matrix => mixed_cdft%matrix%density_matrix
1141 END IF
1142 ALLOCATE (mo_coeff_tmp(nforce_eval, nspins), wmat_tmp(nforce_eval, nvar))
1143 ALLOCATE (nrow_mo(nspins), ncol_mo(nspins))
1144 IF (mixed_cdft%calculate_metric) ALLOCATE (matrix_p_tmp(nforce_eval, nspins))
1145 IF (.NOT. uniform_occupation) THEN
1146 ALLOCATE (mixed_cdft%occupations(nforce_eval, nspins))
1147 ALLOCATE (occno_tmp(nforce_eval, nspins))
1148 END IF
1149 DO iforce_eval = 1, nforce_eval
1150 ! Temporary arrays need to be nulled on every process
1151 DO ispin = 1, nspins
1152 ! Valgrind 3.12/gfortran 4.8.4 oddly complains here (unconditional jump)
1153 ! if mixed_cdft%calculate_metric = .FALSE. and the need to null the array
1154 ! is queried with IF (mixed_cdft%calculate_metric) &
1155 IF (.NOT. uniform_occupation) &
1156 NULLIFY (occno_tmp(iforce_eval, ispin)%array)
1157 END DO
1158 IF (.NOT. ASSOCIATED(force_env%sub_force_env(iforce_eval)%force_env)) cycle
1159 ! From this point onward, we access data local to the sub_force_envs
1160 ! Get qs_env
1161 force_env_qs => force_env%sub_force_env(iforce_eval)%force_env
1162 IF (force_env%mixed_env%do_mixed_qmmm_cdft) THEN
1163 qs_env => force_env_qs%qmmm_env%qs_env
1164 ELSE
1165 CALL force_env_get(force_env_qs, qs_env=qs_env)
1166 END IF
1167 CALL get_qs_env(qs_env, dft_control=dft_control, blacs_env=blacs_env)
1168 ! Store dimensions of the transferred arrays
1169 CALL dbcsr_get_info(dft_control%qs_control%cdft_control%matrix_s%matrix, &
1170 nfullrows_total=nrow_overlap, nfullcols_total=ncol_overlap)
1171 CALL dbcsr_get_info(dft_control%qs_control%cdft_control%wmat(1)%matrix, &
1172 nfullrows_total=nrow_wmat, nfullcols_total=ncol_wmat)
1173 ! MO Coefficients
1174 DO ispin = 1, nspins
1175 CALL cp_fm_get_info(dft_control%qs_control%cdft_control%mo_coeff(ispin), &
1176 ncol_global=ncol_mo(ispin), nrow_global=nrow_mo(ispin))
1177 CALL cp_fm_create(matrix=mo_coeff_tmp(iforce_eval, ispin), &
1178 matrix_struct=dft_control%qs_control%cdft_control%mo_coeff(ispin)%matrix_struct, &
1179 name="MO_COEFF_"//trim(adjustl(cp_to_string(iforce_eval)))//"_" &
1180 //trim(adjustl(cp_to_string(ispin)))//"_MATRIX")
1181 CALL cp_fm_to_fm(dft_control%qs_control%cdft_control%mo_coeff(ispin), &
1182 mo_coeff_tmp(iforce_eval, ispin))
1183 END DO
1184 CALL cp_fm_release(dft_control%qs_control%cdft_control%mo_coeff)
1185 ! Matrix representation(s) of the weight function(s) (dbcsr -> fm)
1186 CALL cp_fm_struct_create(fm_struct_tmp, nrow_global=nrow_wmat, ncol_global=ncol_wmat, context=blacs_env, &
1187 para_env=force_env%sub_force_env(iforce_eval)%force_env%para_env, &
1188 square_blocks=.true.)
1189 DO ivar = 1, nvar
1190 CALL cp_fm_create(wmat_tmp(iforce_eval, ivar), fm_struct_tmp, name="w_matrix")
1191 CALL dbcsr_desymmetrize(dft_control%qs_control%cdft_control%wmat(ivar)%matrix, desymm_tmp)
1192 CALL copy_dbcsr_to_fm(desymm_tmp, wmat_tmp(iforce_eval, ivar))
1193 CALL dbcsr_release(desymm_tmp)
1194 CALL dbcsr_release_p(dft_control%qs_control%cdft_control%wmat(ivar)%matrix)
1195 END DO
1196 DEALLOCATE (dft_control%qs_control%cdft_control%wmat)
1197 CALL cp_fm_struct_release(fm_struct_tmp)
1198 ! Overlap matrix is the same for all sub_force_envs, so we just copy the first one (dbcsr -> fm)
1199 IF (iforce_eval == 1) THEN
1200 CALL cp_fm_struct_create(fm_struct_tmp, nrow_global=nrow_overlap, &
1201 ncol_global=ncol_overlap, context=blacs_env, &
1202 para_env=force_env%sub_force_env(iforce_eval)%force_env%para_env)
1203 CALL cp_fm_create(matrix_s_tmp, fm_struct_tmp, name="s_matrix")
1204 CALL cp_fm_struct_release(fm_struct_tmp)
1205 CALL dbcsr_desymmetrize(dft_control%qs_control%cdft_control%matrix_s%matrix, desymm_tmp)
1206 CALL copy_dbcsr_to_fm(desymm_tmp, matrix_s_tmp)
1207 CALL dbcsr_release(desymm_tmp)
1208 END IF
1209 CALL dbcsr_release_p(dft_control%qs_control%cdft_control%matrix_s%matrix)
1210 ! Density_matrix (dbcsr -> fm)
1211 IF (mixed_cdft%calculate_metric) THEN
1212 DO ispin = 1, nspins
1213 ! Size AOxAO
1214 CALL cp_fm_struct_create(fm_struct_tmp, nrow_global=ncol_overlap, &
1215 ncol_global=ncol_overlap, context=blacs_env, &
1216 para_env=force_env%sub_force_env(iforce_eval)%force_env%para_env)
1217 CALL cp_fm_create(matrix_p_tmp(iforce_eval, ispin), fm_struct_tmp, name="dm_matrix")
1218 CALL cp_fm_struct_release(fm_struct_tmp)
1219 CALL dbcsr_desymmetrize(dft_control%qs_control%cdft_control%matrix_p(ispin)%matrix, desymm_tmp)
1220 CALL copy_dbcsr_to_fm(desymm_tmp, matrix_p_tmp(iforce_eval, ispin))
1221 CALL dbcsr_release(desymm_tmp)
1222 CALL dbcsr_release_p(dft_control%qs_control%cdft_control%matrix_p(ispin)%matrix)
1223 END DO
1224 DEALLOCATE (dft_control%qs_control%cdft_control%matrix_p)
1225 END IF
1226 ! Occupation numbers
1227 IF (.NOT. uniform_occupation) THEN
1228 DO ispin = 1, nspins
1229 IF (ncol_mo(ispin) /= SIZE(dft_control%qs_control%cdft_control%occupations(ispin)%array)) &
1230 cpabort("Array dimensions dont match.")
1231 IF (force_env_qs%para_env%is_source()) THEN
1232 ALLOCATE (occno_tmp(iforce_eval, ispin)%array(ncol_mo(ispin)))
1233 occno_tmp(iforce_eval, ispin)%array = dft_control%qs_control%cdft_control%occupations(ispin)%array
1234 END IF
1235 DEALLOCATE (dft_control%qs_control%cdft_control%occupations(ispin)%array)
1236 END DO
1237 DEALLOCATE (dft_control%qs_control%cdft_control%occupations)
1238 END IF
1239 END DO
1240 ! Create needed fm structs
1241 CALL cp_fm_struct_create(fm_struct_wmat, nrow_global=nrow_wmat, ncol_global=ncol_wmat, &
1242 context=mixed_cdft%blacs_env, para_env=force_env%para_env)
1243 CALL cp_fm_struct_create(fm_struct_overlap, nrow_global=nrow_overlap, ncol_global=ncol_overlap, &
1244 context=mixed_cdft%blacs_env, para_env=force_env%para_env)
1245 ! Redistribute arrays with copy_general (this is not optimal for dbcsr matrices but...)
1246 ! We use this method for the serial case (mixed_cdft%run_type == mixed_cdft_serial) as well to move the arrays to the
1247 ! correct blacs_env, which is impossible using a simple copy of the arrays
1248 ALLOCATE (mixed_wmat_tmp(nforce_eval, nvar))
1249 IF (mixed_cdft%calculate_metric) &
1250 ALLOCATE (mixed_matrix_p_tmp(nforce_eval, nspins))
1251 DO iforce_eval = 1, nforce_eval
1252 ! MO coefficients
1253 DO ispin = 1, nspins
1254 NULLIFY (fm_struct_mo)
1255 CALL cp_fm_struct_create(fm_struct_mo, nrow_global=nrow_mo(ispin), ncol_global=ncol_mo(ispin), &
1256 context=mixed_cdft%blacs_env, para_env=force_env%para_env)
1257 CALL cp_fm_create(matrix=mixed_mo_coeff(iforce_eval, ispin), &
1258 matrix_struct=fm_struct_mo, &
1259 name="MO_COEFF_"//trim(adjustl(cp_to_string(iforce_eval)))//"_" &
1260 //trim(adjustl(cp_to_string(ispin)))//"_MATRIX")
1261 CALL cp_fm_copy_general(mo_coeff_tmp(iforce_eval, ispin), &
1262 mixed_mo_coeff(iforce_eval, ispin), &
1263 mixed_cdft%blacs_env%para_env)
1264 CALL cp_fm_release(mo_coeff_tmp(iforce_eval, ispin))
1265 CALL cp_fm_struct_release(fm_struct_mo)
1266 END DO
1267 ! Weight
1268 DO ivar = 1, nvar
1269 NULLIFY (w_matrix(iforce_eval, ivar)%matrix)
1270 CALL dbcsr_init_p(w_matrix(iforce_eval, ivar)%matrix)
1271 CALL cp_fm_create(matrix=mixed_wmat_tmp(iforce_eval, ivar), &
1272 matrix_struct=fm_struct_wmat, &
1273 name="WEIGHT_"//trim(adjustl(cp_to_string(iforce_eval)))//"_MATRIX")
1274 CALL cp_fm_copy_general(wmat_tmp(iforce_eval, ivar), &
1275 mixed_wmat_tmp(iforce_eval, ivar), &
1276 mixed_cdft%blacs_env%para_env)
1277 CALL cp_fm_release(wmat_tmp(iforce_eval, ivar))
1278 ! (fm -> dbcsr)
1279 CALL copy_fm_to_dbcsr_bc(mixed_wmat_tmp(iforce_eval, ivar), &
1280 w_matrix(iforce_eval, ivar)%matrix)
1281 CALL cp_fm_release(mixed_wmat_tmp(iforce_eval, ivar))
1282 END DO
1283 ! Density matrix (fm -> dbcsr)
1284 IF (mixed_cdft%calculate_metric) THEN
1285 DO ispin = 1, nspins
1286 NULLIFY (density_matrix(iforce_eval, ispin)%matrix)
1287 CALL dbcsr_init_p(density_matrix(iforce_eval, ispin)%matrix)
1288 CALL cp_fm_create(matrix=mixed_matrix_p_tmp(iforce_eval, ispin), &
1289 matrix_struct=fm_struct_overlap, &
1290 name="DENSITY_"//trim(adjustl(cp_to_string(iforce_eval)))//"_"// &
1291 trim(adjustl(cp_to_string(ispin)))//"_MATRIX")
1292 CALL cp_fm_copy_general(matrix_p_tmp(iforce_eval, ispin), &
1293 mixed_matrix_p_tmp(iforce_eval, ispin), &
1294 mixed_cdft%blacs_env%para_env)
1295 CALL cp_fm_release(matrix_p_tmp(iforce_eval, ispin))
1296 CALL copy_fm_to_dbcsr_bc(mixed_matrix_p_tmp(iforce_eval, ispin), &
1297 density_matrix(iforce_eval, ispin)%matrix)
1298 CALL cp_fm_release(mixed_matrix_p_tmp(iforce_eval, ispin))
1299 END DO
1300 END IF
1301 END DO
1302 CALL cp_fm_struct_release(fm_struct_wmat)
1303 DEALLOCATE (mo_coeff_tmp, wmat_tmp, mixed_wmat_tmp)
1304 IF (mixed_cdft%calculate_metric) THEN
1305 DEALLOCATE (matrix_p_tmp)
1306 DEALLOCATE (mixed_matrix_p_tmp)
1307 END IF
1308 ! Overlap (fm -> dbcsr)
1309 CALL cp_fm_create(matrix=mixed_matrix_s_tmp, &
1310 matrix_struct=fm_struct_overlap, &
1311 name="OVERLAP_MATRIX")
1312 CALL cp_fm_struct_release(fm_struct_overlap)
1313 CALL cp_fm_copy_general(matrix_s_tmp, &
1314 mixed_matrix_s_tmp, &
1315 mixed_cdft%blacs_env%para_env)
1316 CALL cp_fm_release(matrix_s_tmp)
1317 CALL copy_fm_to_dbcsr_bc(mixed_matrix_s_tmp, mixed_matrix_s)
1318 CALL cp_fm_release(mixed_matrix_s_tmp)
1319 ! Occupation numbers
1320 IF (.NOT. uniform_occupation) THEN
1321 DO iforce_eval = 1, nforce_eval
1322 DO ispin = 1, nspins
1323 ALLOCATE (mixed_cdft%occupations(iforce_eval, ispin)%array(ncol_mo(ispin)))
1324 mixed_cdft%occupations(iforce_eval, ispin)%array = 0.0_dp
1325 IF (ASSOCIATED(occno_tmp(iforce_eval, ispin)%array)) THEN
1326 mixed_cdft%occupations(iforce_eval, ispin)%array = occno_tmp(iforce_eval, ispin)%array
1327 DEALLOCATE (occno_tmp(iforce_eval, ispin)%array)
1328 END IF
1329 CALL force_env%para_env%sum(mixed_cdft%occupations(iforce_eval, ispin)%array)
1330 END DO
1331 END DO
1332 DEALLOCATE (occno_tmp)
1333 END IF
1334 DEALLOCATE (ncol_mo, nrow_mo)
1335
1336 END SUBROUTINE mixed_cdft_redistribute_arrays
1337! **************************************************************************************************
1338!> \brief Routine to print out the electronic coupling(s) between CDFT states.
1339!> \param force_env the force_env that holds the CDFT states
1340!> \par History
1341!> 11.17 created [Nico Holmberg]
1342! **************************************************************************************************
1343 SUBROUTINE mixed_cdft_print_couplings(force_env)
1344 TYPE(force_env_type), POINTER :: force_env
1345
1346 INTEGER :: iounit, ipermutation, istate, ivar, &
1347 jstate, nforce_eval, npermutations, &
1348 nvar
1349 TYPE(cp_logger_type), POINTER :: logger
1350 TYPE(mixed_cdft_type), POINTER :: mixed_cdft
1351 TYPE(section_vals_type), POINTER :: force_env_section, print_section
1352
1353 NULLIFY (print_section, mixed_cdft)
1354
1355 logger => cp_get_default_logger()
1356 cpassert(ASSOCIATED(force_env))
1357 CALL force_env_get(force_env=force_env, &
1358 force_env_section=force_env_section)
1359 CALL get_mixed_env(force_env%mixed_env, cdft_control=mixed_cdft)
1360 cpassert(ASSOCIATED(mixed_cdft))
1361 print_section => section_vals_get_subs_vals(force_env_section, "MIXED%MIXED_CDFT%PRINT%PROGRAM_RUN_INFO")
1362 iounit = cp_print_key_unit_nr(logger, print_section, '', extension='.mixedLog')
1363 !
1364 cpassert(ALLOCATED(mixed_cdft%results%strength))
1365 cpassert(ALLOCATED(mixed_cdft%results%W_diagonal))
1366 cpassert(ALLOCATED(mixed_cdft%results%S))
1367 cpassert(ALLOCATED(mixed_cdft%results%energy))
1368 nforce_eval = SIZE(force_env%sub_force_env)
1369 nvar = SIZE(mixed_cdft%results%strength, 1)
1370 npermutations = nforce_eval*(nforce_eval - 1)/2 ! Size of upper triangular part
1371 IF (iounit > 0) THEN
1372 WRITE (iounit, '(/,T3,A,T66)') &
1373 '------------------------- CDFT coupling information --------------------------'
1374 WRITE (iounit, '(T3,A,T66,(3X,F12.2))') &
1375 'Information at step (fs):', mixed_cdft%sim_step*mixed_cdft%sim_dt
1376 DO ipermutation = 1, npermutations
1377 CALL map_permutation_to_states(nforce_eval, ipermutation, istate, jstate)
1378 WRITE (iounit, '(/,T3,A)') repeat('#', 44)
1379 WRITE (iounit, '(T3,A,I3,A,I3,A)') '###### CDFT states I =', istate, ' and J = ', jstate, ' ######'
1380 WRITE (iounit, '(T3,A)') repeat('#', 44)
1381 DO ivar = 1, nvar
1382 IF (ivar > 1) &
1383 WRITE (iounit, '(A)') ''
1384 WRITE (iounit, '(T3,A,T60,(3X,I18))') 'Atomic group:', ivar
1385 WRITE (iounit, '(T3,A,T60,(3X,F18.12))') &
1386 'Strength of constraint I:', mixed_cdft%results%strength(ivar, istate)
1387 WRITE (iounit, '(T3,A,T60,(3X,F18.12))') &
1388 'Strength of constraint J:', mixed_cdft%results%strength(ivar, jstate)
1389 WRITE (iounit, '(T3,A,T60,(3X,F18.12))') &
1390 'Final value of constraint I:', mixed_cdft%results%W_diagonal(ivar, istate)
1391 WRITE (iounit, '(T3,A,T60,(3X,F18.12))') &
1392 'Final value of constraint J:', mixed_cdft%results%W_diagonal(ivar, jstate)
1393 END DO
1394 WRITE (iounit, '(/,T3,A,T60,(3X,F18.12))') &
1395 'Overlap between states I and J:', mixed_cdft%results%S(istate, jstate)
1396 WRITE (iounit, '(T3,A,T60,(3X,F18.12))') &
1397 'Charge transfer energy (J-I) (Hartree):', (mixed_cdft%results%energy(jstate) - mixed_cdft%results%energy(istate))
1398 WRITE (iounit, *)
1399 IF (ALLOCATED(mixed_cdft%results%rotation)) THEN
1400 IF (abs(mixed_cdft%results%rotation(ipermutation))*1.0e3_dp .GE. 0.1_dp) THEN
1401 WRITE (iounit, '(T3,A,T60,(3X,F18.12))') &
1402 'Diabatic electronic coupling (rotation, mHartree):', &
1403 abs(mixed_cdft%results%rotation(ipermutation)*1.0e3_dp)
1404 ELSE
1405 WRITE (iounit, '(T3,A,T60,(3X,F18.12))') &
1406 'Diabatic electronic coupling (rotation, microHartree):', &
1407 abs(mixed_cdft%results%rotation(ipermutation)*1.0e6_dp)
1408 END IF
1409 END IF
1410 IF (ALLOCATED(mixed_cdft%results%lowdin)) THEN
1411 IF (abs(mixed_cdft%results%lowdin(ipermutation))*1.0e3_dp .GE. 0.1_dp) THEN
1412 WRITE (iounit, '(T3,A,T60,(3X,F18.12))') &
1413 'Diabatic electronic coupling (Lowdin, mHartree):', &
1414 abs(mixed_cdft%results%lowdin(ipermutation)*1.0e3_dp)
1415 ELSE
1416 WRITE (iounit, '(T3,A,T60,(3X,F18.12))') &
1417 'Diabatic electronic coupling (Lowdin, microHartree):', &
1418 abs(mixed_cdft%results%lowdin(ipermutation)*1.0e6_dp)
1419 END IF
1420 END IF
1421 IF (ALLOCATED(mixed_cdft%results%wfn)) THEN
1422 IF (mixed_cdft%results%wfn(ipermutation)*1.0e3_dp .GE. 0.1_dp) THEN
1423 WRITE (iounit, '(T3,A,T60,(3X,F18.12))') &
1424 'Diabatic electronic coupling (wfn overlap, mHartree):', &
1425 abs(mixed_cdft%results%wfn(ipermutation)*1.0e3_dp)
1426 ELSE
1427 WRITE (iounit, '(T3,A,T60,(3X,F18.12))') &
1428 'Diabatic electronic coupling (wfn overlap, microHartree):', &
1429 abs(mixed_cdft%results%wfn(ipermutation)*1.0e6_dp)
1430 END IF
1431 END IF
1432 IF (ALLOCATED(mixed_cdft%results%nonortho)) THEN
1433 WRITE (iounit, '(T3,A,T60,(3X,F18.12))') &
1434 'Diabatic electronic coupling (nonorthogonal, Hartree):', mixed_cdft%results%nonortho(ipermutation)
1435 END IF
1436 IF (ALLOCATED(mixed_cdft%results%metric)) THEN
1437 WRITE (iounit, *)
1438 IF (SIZE(mixed_cdft%results%metric, 2) == 1) THEN
1439 WRITE (iounit, '(T3,A,T66,(3X,F12.6))') &
1440 'Coupling reliability metric (0 is ideal):', mixed_cdft%results%metric(ipermutation, 1)
1441 ELSE
1442 WRITE (iounit, '(T3,A,T54,(3X,2F12.6))') &
1443 'Coupling reliability metric (0 is ideal):', &
1444 mixed_cdft%results%metric(ipermutation, 1), mixed_cdft%results%metric(ipermutation, 2)
1445 END IF
1446 END IF
1447 END DO
1448 WRITE (iounit, '(T3,A)') &
1449 '------------------------------------------------------------------------------'
1450 END IF
1451 CALL cp_print_key_finished_output(iounit, logger, force_env_section, &
1452 "MIXED%MIXED_CDFT%PRINT%PROGRAM_RUN_INFO")
1453
1454 END SUBROUTINE mixed_cdft_print_couplings
1455
1456! **************************************************************************************************
1457!> \brief Release storage reserved for mixed CDFT matrices
1458!> \param force_env the force_env that holds the CDFT states
1459!> \par History
1460!> 11.17 created [Nico Holmberg]
1461! **************************************************************************************************
1462 SUBROUTINE mixed_cdft_release_work(force_env)
1463 TYPE(force_env_type), POINTER :: force_env
1464
1465 TYPE(mixed_cdft_type), POINTER :: mixed_cdft
1466
1467 NULLIFY (mixed_cdft)
1468
1469 cpassert(ASSOCIATED(force_env))
1470 CALL get_mixed_env(force_env%mixed_env, cdft_control=mixed_cdft)
1471 cpassert(ASSOCIATED(mixed_cdft))
1472 CALL mixed_cdft_result_type_release(mixed_cdft%results)
1473
1474 END SUBROUTINE mixed_cdft_release_work
1475
1476! **************************************************************************************************
1477!> \brief Given the size of a symmetric matrix and a permutation index, returns indices (i, j) of the
1478!> off-diagonal element that corresponds to the permutation index. Assumes that the permutation
1479!> index was computed by going through the upper triangular part of the input matrix row-by-row.
1480!> \param n the size of the symmetric matrix
1481!> \param ipermutation the permutation index
1482!> \param i the row index corresponding to ipermutation
1483!> \param j the column index corresponding to ipermutation
1484! **************************************************************************************************
1485 SUBROUTINE map_permutation_to_states(n, ipermutation, i, j)
1486 INTEGER, INTENT(IN) :: n, ipermutation
1487 INTEGER, INTENT(OUT) :: i, j
1488
1489 INTEGER :: kcol, kpermutation, krow, npermutations
1490
1491 npermutations = n*(n - 1)/2 ! Size of upper triangular part
1492 IF (ipermutation > npermutations) &
1493 cpabort("Permutation index out of bounds")
1494 kpermutation = 0
1495 DO krow = 1, n
1496 DO kcol = krow + 1, n
1497 kpermutation = kpermutation + 1
1498 IF (kpermutation == ipermutation) THEN
1499 i = krow
1500 j = kcol
1501 RETURN
1502 END IF
1503 END DO
1504 END DO
1505
1506 END SUBROUTINE map_permutation_to_states
1507
1508! **************************************************************************************************
1509!> \brief Determine confinement bounds along confinement dir (hardcoded to be z)
1510!> and determine the number of nonzero entries
1511!> Optionally zero entries below a given threshold
1512!> \param fun input 3D potential (real space)
1513!> \param th threshold for screening values
1514!> \param just_zero determines if fun should only be zeroed without returning bounds/work
1515!> \param bounds the confinement bounds: fun is nonzero only between these values along 3rd dimension
1516!> \param work an estimate of the total number of grid points where fun is nonzero
1517! **************************************************************************************************
1518 SUBROUTINE hfun_zero(fun, th, just_zero, bounds, work)
1519 REAL(kind=dp), DIMENSION(:, :, :), INTENT(INOUT) :: fun
1520 REAL(kind=dp), INTENT(IN) :: th
1521 LOGICAL :: just_zero
1522 INTEGER, OPTIONAL :: bounds(2), work
1523
1524 INTEGER :: i1, i2, i3, lb, n1, n2, n3, nzeroed, &
1525 nzeroed_total, ub
1526 LOGICAL :: lb_final, ub_final
1527
1528 n1 = SIZE(fun, 1)
1529 n2 = SIZE(fun, 2)
1530 n3 = SIZE(fun, 3)
1531 nzeroed_total = 0
1532 IF (.NOT. just_zero) THEN
1533 cpassert(PRESENT(bounds))
1534 cpassert(PRESENT(work))
1535 lb = 1
1536 lb_final = .false.
1537 ub_final = .false.
1538 END IF
1539 DO i3 = 1, n3
1540 IF (.NOT. just_zero) nzeroed = 0
1541 DO i2 = 1, n2
1542 DO i1 = 1, n1
1543 IF (fun(i1, i2, i3) < th) THEN
1544 IF (.NOT. just_zero) THEN
1545 nzeroed = nzeroed + 1
1546 nzeroed_total = nzeroed_total + 1
1547 ELSE
1548 fun(i1, i2, i3) = 0.0_dp
1549 END IF
1550 END IF
1551 END DO
1552 END DO
1553 IF (.NOT. just_zero) THEN
1554 IF (nzeroed == (n2*n1)) THEN
1555 IF (.NOT. lb_final) THEN
1556 lb = i3
1557 ELSE IF (.NOT. ub_final) THEN
1558 ub = i3
1559 ub_final = .true.
1560 END IF
1561 ELSE
1562 IF (.NOT. lb_final) lb_final = .true.
1563 IF (ub_final) ub_final = .false. ! Safeguard against "holes"
1564 END IF
1565 END IF
1566 END DO
1567 IF (.NOT. just_zero) THEN
1568 IF (.NOT. ub_final) ub = n3
1569 bounds(1) = lb
1570 bounds(2) = ub
1571 bounds = bounds - (n3/2) - 1
1572 work = n3*n2*n1 - nzeroed_total
1573 END IF
1574
1575 END SUBROUTINE hfun_zero
1576
1577! **************************************************************************************************
1578!> \brief Read input section related to block diagonalization of the mixed CDFT Hamiltonian matrix.
1579!> \param force_env the force_env that holds the CDFT states
1580!> \param blocks list of CDFT states defining the matrix blocks
1581!> \param ignore_excited flag that determines if excited states resulting from the block
1582!> diagonalization process should be ignored
1583!> \param nrecursion integer that determines how many steps of recursive block diagonalization
1584!> is performed (1 if disabled)
1585!> \par History
1586!> 01.18 created [Nico Holmberg]
1587! **************************************************************************************************
1588 SUBROUTINE mixed_cdft_read_block_diag(force_env, blocks, ignore_excited, nrecursion)
1589 TYPE(force_env_type), POINTER :: force_env
1590 TYPE(cp_1d_i_p_type), ALLOCATABLE, DIMENSION(:), &
1591 INTENT(OUT) :: blocks
1592 LOGICAL, INTENT(OUT) :: ignore_excited
1593 INTEGER, INTENT(OUT) :: nrecursion
1594
1595 INTEGER :: i, j, k, l, nblk, nforce_eval
1596 INTEGER, DIMENSION(:), POINTER :: tmplist
1597 LOGICAL :: do_recursive, explicit, has_duplicates
1598 TYPE(section_vals_type), POINTER :: block_section, force_env_section
1599
1600 EXTERNAL :: dsygv
1601
1602 NULLIFY (force_env_section, block_section)
1603 cpassert(ASSOCIATED(force_env))
1604 nforce_eval = SIZE(force_env%sub_force_env)
1605
1606 CALL force_env_get(force_env=force_env, &
1607 force_env_section=force_env_section)
1608 block_section => section_vals_get_subs_vals(force_env_section, "MIXED%MIXED_CDFT%BLOCK_DIAGONALIZE")
1609
1610 CALL section_vals_get(block_section, explicit=explicit)
1611 IF (.NOT. explicit) &
1612 CALL cp_abort(__location__, &
1613 "Block diagonalization of CDFT Hamiltonian was requested, but the "// &
1614 "corresponding input section is missing!")
1615
1616 CALL section_vals_val_get(block_section, "BLOCK", n_rep_val=nblk)
1617 ALLOCATE (blocks(nblk))
1618 DO i = 1, nblk
1619 NULLIFY (blocks(i)%array)
1620 CALL section_vals_val_get(block_section, "BLOCK", i_rep_val=i, i_vals=tmplist)
1621 IF (SIZE(tmplist) < 1) &
1622 cpabort("Each BLOCK must contain at least 1 state.")
1623 ALLOCATE (blocks(i)%array(SIZE(tmplist)))
1624 blocks(i)%array(:) = tmplist(:)
1625 END DO
1626 CALL section_vals_val_get(block_section, "IGNORE_EXCITED", l_val=ignore_excited)
1627 CALL section_vals_val_get(block_section, "RECURSIVE_DIAGONALIZATION", l_val=do_recursive)
1628 ! Check that the requested states exist
1629 DO i = 1, nblk
1630 DO j = 1, SIZE(blocks(i)%array)
1631 IF (blocks(i)%array(j) < 1 .OR. blocks(i)%array(j) > nforce_eval) &
1632 cpabort("Requested state does not exist.")
1633 END DO
1634 END DO
1635 ! Check for duplicates
1636 has_duplicates = .false.
1637 DO i = 1, nblk
1638 ! Within same block
1639 DO j = 1, SIZE(blocks(i)%array)
1640 DO k = j + 1, SIZE(blocks(i)%array)
1641 IF (blocks(i)%array(j) == blocks(i)%array(k)) has_duplicates = .true.
1642 END DO
1643 END DO
1644 ! Within different blocks
1645 DO j = i + 1, nblk
1646 DO k = 1, SIZE(blocks(i)%array)
1647 DO l = 1, SIZE(blocks(j)%array)
1648 IF (blocks(i)%array(k) == blocks(j)%array(l)) has_duplicates = .true.
1649 END DO
1650 END DO
1651 END DO
1652 END DO
1653 IF (has_duplicates) cpabort("Duplicate states are not allowed.")
1654 nrecursion = 1
1655 IF (do_recursive) THEN
1656 IF (modulo(nblk, 2) /= 0) THEN
1657 CALL cp_warn(__location__, &
1658 "Number of blocks not divisible with 2. Recursive diagonalization not possible. "// &
1659 "Calculation proceeds without.")
1660 nrecursion = 1
1661 ELSE
1662 nrecursion = nblk/2
1663 END IF
1664 IF (nrecursion /= 1 .AND. .NOT. ignore_excited) &
1665 CALL cp_abort(__location__, &
1666 "Keyword IGNORE_EXCITED must be active for recursive diagonalization.")
1667 END IF
1668
1669 END SUBROUTINE mixed_cdft_read_block_diag
1670
1671! **************************************************************************************************
1672!> \brief Assembles the matrix blocks from the mixed CDFT Hamiltonian.
1673!> \param mixed_cdft the env that holds the CDFT states
1674!> \param blocks list of CDFT states defining the matrix blocks
1675!> \param H_block list of Hamiltonian matrix blocks
1676!> \param S_block list of overlap matrix blocks
1677!> \par History
1678!> 01.18 created [Nico Holmberg]
1679! **************************************************************************************************
1680 SUBROUTINE mixed_cdft_get_blocks(mixed_cdft, blocks, H_block, S_block)
1681 TYPE(mixed_cdft_type), POINTER :: mixed_cdft
1682 TYPE(cp_1d_i_p_type), ALLOCATABLE, DIMENSION(:) :: blocks
1683 TYPE(cp_2d_r_p_type), ALLOCATABLE, DIMENSION(:), &
1684 INTENT(OUT) :: h_block, s_block
1685
1686 INTEGER :: i, icol, irow, j, k, nblk
1687
1688 EXTERNAL :: dsygv
1689
1690 cpassert(ASSOCIATED(mixed_cdft))
1691
1692 nblk = SIZE(blocks)
1693 ALLOCATE (h_block(nblk), s_block(nblk))
1694 DO i = 1, nblk
1695 NULLIFY (h_block(i)%array)
1696 NULLIFY (s_block(i)%array)
1697 ALLOCATE (h_block(i)%array(SIZE(blocks(i)%array), SIZE(blocks(i)%array)))
1698 ALLOCATE (s_block(i)%array(SIZE(blocks(i)%array), SIZE(blocks(i)%array)))
1699 icol = 0
1700 DO j = 1, SIZE(blocks(i)%array)
1701 irow = 0
1702 icol = icol + 1
1703 DO k = 1, SIZE(blocks(i)%array)
1704 irow = irow + 1
1705 h_block(i)%array(irow, icol) = mixed_cdft%results%H(blocks(i)%array(k), blocks(i)%array(j))
1706 s_block(i)%array(irow, icol) = mixed_cdft%results%S(blocks(i)%array(k), blocks(i)%array(j))
1707 END DO
1708 END DO
1709 ! Check that none of the interaction energies is repulsive
1710 IF (any(h_block(i)%array .GE. 0.0_dp)) &
1711 CALL cp_abort(__location__, &
1712 "At least one of the interaction energies within block "//trim(adjustl(cp_to_string(i)))// &
1713 " is repulsive.")
1714 END DO
1715
1716 END SUBROUTINE mixed_cdft_get_blocks
1717
1718! **************************************************************************************************
1719!> \brief Diagonalizes each of the matrix blocks.
1720!> \param blocks list of CDFT states defining the matrix blocks
1721!> \param H_block list of Hamiltonian matrix blocks
1722!> \param S_block list of overlap matrix blocks
1723!> \param eigenvalues list of eigenvalues for each block
1724!> \par History
1725!> 01.18 created [Nico Holmberg]
1726! **************************************************************************************************
1727 SUBROUTINE mixed_cdft_diagonalize_blocks(blocks, H_block, S_block, eigenvalues)
1728 TYPE(cp_1d_i_p_type), ALLOCATABLE, DIMENSION(:) :: blocks
1729 TYPE(cp_2d_r_p_type), ALLOCATABLE, DIMENSION(:) :: h_block, s_block
1730 TYPE(cp_1d_r_p_type), ALLOCATABLE, DIMENSION(:), &
1731 INTENT(OUT) :: eigenvalues
1732
1733 INTEGER :: i, info, nblk, work_array_size
1734 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: work
1735 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :) :: h_mat_copy, s_mat_copy
1736
1737 EXTERNAL :: dsygv
1738
1739 nblk = SIZE(blocks)
1740 ALLOCATE (eigenvalues(nblk))
1741 DO i = 1, nblk
1742 NULLIFY (eigenvalues(i)%array)
1743 ALLOCATE (eigenvalues(i)%array(SIZE(blocks(i)%array)))
1744 eigenvalues(i)%array = 0.0_dp
1745 ! Workspace query
1746 ALLOCATE (work(1))
1747 info = 0
1748 ALLOCATE (h_mat_copy(SIZE(blocks(i)%array), SIZE(blocks(i)%array)))
1749 ALLOCATE (s_mat_copy(SIZE(blocks(i)%array), SIZE(blocks(i)%array)))
1750 h_mat_copy(:, :) = h_block(i)%array(:, :) ! Need explicit copies because dsygv destroys original values
1751 s_mat_copy(:, :) = s_block(i)%array(:, :)
1752 CALL dsygv(1, 'V', 'U', SIZE(blocks(i)%array), h_mat_copy, SIZE(blocks(i)%array), &
1753 s_mat_copy, SIZE(blocks(i)%array), eigenvalues(i)%array, work, -1, info)
1754 work_array_size = nint(work(1))
1755 DEALLOCATE (h_mat_copy, s_mat_copy)
1756 ! Allocate work array
1757 DEALLOCATE (work)
1758 ALLOCATE (work(work_array_size))
1759 work = 0.0_dp
1760 ! Solve Hc = eSc
1761 info = 0
1762 CALL dsygv(1, 'V', 'U', SIZE(blocks(i)%array), h_block(i)%array, SIZE(blocks(i)%array), &
1763 s_block(i)%array, SIZE(blocks(i)%array), eigenvalues(i)%array, work, work_array_size, info)
1764 IF (info /= 0) THEN
1765 IF (info > SIZE(blocks(i)%array)) THEN
1766 cpabort("Matrix S is not positive definite")
1767 ELSE
1768 cpabort("Diagonalization of H matrix failed.")
1769 END IF
1770 END IF
1771 DEALLOCATE (work)
1772 END DO
1773
1774 END SUBROUTINE mixed_cdft_diagonalize_blocks
1775
1776! **************************************************************************************************
1777!> \brief Assembles the new block diagonalized mixed CDFT Hamiltonian and overlap matrices.
1778!> \param mixed_cdft the env that holds the CDFT states
1779!> \param blocks list of CDFT states defining the matrix blocks
1780!> \param H_block list of Hamiltonian matrix blocks
1781!> \param eigenvalues list of eigenvalues for each block
1782!> \param n size of the new Hamiltonian and overlap matrices
1783!> \param iounit the output unit
1784!> \par History
1785!> 01.18 created [Nico Holmberg]
1786! **************************************************************************************************
1787 SUBROUTINE mixed_cdft_assemble_block_diag(mixed_cdft, blocks, H_block, eigenvalues, &
1788 n, iounit)
1789 TYPE(mixed_cdft_type), POINTER :: mixed_cdft
1790 TYPE(cp_1d_i_p_type), ALLOCATABLE, DIMENSION(:) :: blocks
1791 TYPE(cp_2d_r_p_type), ALLOCATABLE, DIMENSION(:) :: h_block
1792 TYPE(cp_1d_r_p_type), ALLOCATABLE, DIMENSION(:) :: eigenvalues
1793 INTEGER :: n, iounit
1794
1795 CHARACTER(LEN=20) :: ilabel, jlabel
1796 CHARACTER(LEN=3) :: tmp
1797 INTEGER :: i, icol, ipermutation, irow, j, k, l, &
1798 nblk, npermutations
1799 LOGICAL :: ignore_excited
1800 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :) :: h_mat, h_offdiag, s_mat, s_offdiag
1801
1802 EXTERNAL :: dsygv
1803
1804 ALLOCATE (h_mat(n, n), s_mat(n, n))
1805 nblk = SIZE(blocks)
1806 ignore_excited = (nblk == n)
1807 ! The diagonal contains the eigenvalues of each block
1808 IF (iounit > 0) WRITE (iounit, '(/,T3,A)') "Eigenvalues of the block diagonalized states"
1809 h_mat(:, :) = 0.0_dp
1810 s_mat(:, :) = 0.0_dp
1811 k = 1
1812 DO i = 1, nblk
1813 IF (iounit > 0) WRITE (iounit, '(T6,A,I3)') "Block", i
1814 DO j = 1, SIZE(eigenvalues(i)%array)
1815 h_mat(k, k) = eigenvalues(i)%array(j)
1816 s_mat(k, k) = 1.0_dp
1817 k = k + 1
1818 IF (iounit > 0) THEN
1819 IF (j == 1) THEN
1820 WRITE (iounit, '(T9,A,T58,(3X,F20.14))') 'Ground state energy:', eigenvalues(i)%array(j)
1821 ELSE
1822 WRITE (iounit, '(T9,A,I2,A,T58,(3X,F20.14))') &
1823 'Excited state (', j - 1, ' ) energy:', eigenvalues(i)%array(j)
1824 END IF
1825 END IF
1826 IF (ignore_excited .AND. j == 1) EXIT
1827 END DO
1828 END DO
1829 ! Transform the off-diagonal blocks using the eigenvectors of each block
1830 npermutations = nblk*(nblk - 1)/2
1831 IF (iounit > 0) WRITE (iounit, '(/,T3,A)') "Interactions between block diagonalized states"
1832 DO ipermutation = 1, npermutations
1833 CALL map_permutation_to_states(nblk, ipermutation, i, j)
1834 ! Get the untransformed off-diagonal block
1835 ALLOCATE (h_offdiag(SIZE(blocks(i)%array), SIZE(blocks(j)%array)))
1836 ALLOCATE (s_offdiag(SIZE(blocks(i)%array), SIZE(blocks(j)%array)))
1837 icol = 0
1838 DO k = 1, SIZE(blocks(j)%array)
1839 irow = 0
1840 icol = icol + 1
1841 DO l = 1, SIZE(blocks(i)%array)
1842 irow = irow + 1
1843 h_offdiag(irow, icol) = mixed_cdft%results%H(blocks(i)%array(l), blocks(j)%array(k))
1844 s_offdiag(irow, icol) = mixed_cdft%results%S(blocks(i)%array(l), blocks(j)%array(k))
1845 END DO
1846 END DO
1847 ! Check that none of the interaction energies is repulsive
1848 IF (any(h_offdiag .GE. 0.0_dp)) &
1849 CALL cp_abort(__location__, &
1850 "At least one of the interaction energies between blocks "//trim(adjustl(cp_to_string(i)))// &
1851 " and "//trim(adjustl(cp_to_string(j)))//" is repulsive.")
1852 ! Now transform: C_i^T * H * C_j
1853 h_offdiag(:, :) = matmul(h_offdiag, h_block(j)%array)
1854 h_offdiag(:, :) = matmul(transpose(h_block(i)%array), h_offdiag)
1855 s_offdiag(:, :) = matmul(s_offdiag, h_block(j)%array)
1856 s_offdiag(:, :) = matmul(transpose(h_block(i)%array), s_offdiag)
1857 ! Make sure the transformation preserves the sign of elements in the S and H matrices
1858 ! The S/H matrices contain only positive/negative values so that any sign flipping occurs in the
1859 ! same elements in both matrices
1860 ! Check for sign flipping using the S matrix
1861 IF (any(s_offdiag .LT. 0.0_dp)) THEN
1862 DO l = 1, SIZE(s_offdiag, 2)
1863 DO k = 1, SIZE(s_offdiag, 1)
1864 IF (s_offdiag(k, l) .LT. 0.0_dp) THEN
1865 s_offdiag(k, l) = -1.0_dp*s_offdiag(k, l)
1866 h_offdiag(k, l) = -1.0_dp*h_offdiag(k, l)
1867 END IF
1868 END DO
1869 END DO
1870 END IF
1871 IF (ignore_excited) THEN
1872 h_mat(i, j) = h_offdiag(1, 1)
1873 h_mat(j, i) = h_mat(i, j)
1874 s_mat(i, j) = s_offdiag(1, 1)
1875 s_mat(j, i) = s_mat(i, j)
1876 ELSE
1877 irow = 1
1878 icol = 1
1879 DO k = 1, i - 1
1880 irow = irow + SIZE(blocks(k)%array)
1881 END DO
1882 DO k = 1, j - 1
1883 icol = icol + SIZE(blocks(k)%array)
1884 END DO
1885 h_mat(irow:irow + SIZE(h_offdiag, 1) - 1, icol:icol + SIZE(h_offdiag, 2) - 1) = h_offdiag(:, :)
1886 h_mat(icol:icol + SIZE(h_offdiag, 2) - 1, irow:irow + SIZE(h_offdiag, 1) - 1) = transpose(h_offdiag)
1887 s_mat(irow:irow + SIZE(h_offdiag, 1) - 1, icol:icol + SIZE(h_offdiag, 2) - 1) = s_offdiag(:, :)
1888 s_mat(icol:icol + SIZE(h_offdiag, 2) - 1, irow:irow + SIZE(h_offdiag, 1) - 1) = transpose(s_offdiag)
1889 END IF
1890 IF (iounit > 0) THEN
1891 WRITE (iounit, '(/,T3,A)') repeat('#', 39)
1892 WRITE (iounit, '(T3,A,I3,A,I3,A)') '###### Blocks I =', i, ' and J = ', j, ' ######'
1893 WRITE (iounit, '(T3,A)') repeat('#', 39)
1894 WRITE (iounit, '(T3,A)') 'Interaction energies'
1895 DO irow = 1, SIZE(h_offdiag, 1)
1896 ilabel = "(ground state)"
1897 IF (irow > 1) THEN
1898 IF (ignore_excited) EXIT
1899 WRITE (tmp, '(I3)') irow - 1
1900 ilabel = "(excited state "//trim(adjustl(tmp))//")"
1901 END IF
1902 DO icol = 1, SIZE(h_offdiag, 2)
1903 jlabel = "(ground state)"
1904 IF (icol > 1) THEN
1905 IF (ignore_excited) EXIT
1906 WRITE (tmp, '(I3)') icol - 1
1907 jlabel = "(excited state "//trim(adjustl(tmp))//")"
1908 END IF
1909 WRITE (iounit, '(T6,A,T58,(3X,F20.14))') trim(ilabel)//'-'//trim(jlabel)//':', h_offdiag(irow, icol)
1910 END DO
1911 END DO
1912 WRITE (iounit, '(T3,A)') 'Overlaps'
1913 DO irow = 1, SIZE(h_offdiag, 1)
1914 ilabel = "(ground state)"
1915 IF (irow > 1) THEN
1916 IF (ignore_excited) EXIT
1917 ilabel = "(excited state)"
1918 WRITE (tmp, '(I3)') irow - 1
1919 ilabel = "(excited state "//trim(adjustl(tmp))//")"
1920 END IF
1921 DO icol = 1, SIZE(h_offdiag, 2)
1922 jlabel = "(ground state)"
1923 IF (icol > 1) THEN
1924 IF (ignore_excited) EXIT
1925 WRITE (tmp, '(I3)') icol - 1
1926 jlabel = "(excited state "//trim(adjustl(tmp))//")"
1927 END IF
1928 WRITE (iounit, '(T6,A,T58,(3X,F20.14))') trim(ilabel)//'-'//trim(jlabel)//':', s_offdiag(irow, icol)
1929 END DO
1930 END DO
1931 END IF
1932 DEALLOCATE (h_offdiag, s_offdiag)
1933 END DO
1934 CALL mixed_cdft_result_type_set(mixed_cdft%results, h=h_mat, s=s_mat)
1935 ! Deallocate work
1936 DEALLOCATE (h_mat, s_mat)
1937
1938 END SUBROUTINE mixed_cdft_assemble_block_diag
1939
1940END MODULE mixed_cdft_utils
static GRID_HOST_DEVICE int modulo(int a, int m)
Equivalent of Fortran's MODULO, which always return a positive number. https://gcc....
Define the atomic kind types and their sub types.
Handles all functions related to the CELL.
Definition cell_types.F:15
various utilities that regard array of different kinds: output, allocation,... maybe it is not a good...
methods related to the blacs parallel environment
subroutine, public cp_blacs_env_create(blacs_env, para_env, blacs_grid_layout, blacs_repeatable, row_major, grid_2d)
allocates and initializes a type that represent a blacs context
Defines control structures, which contain the parameters and the settings for the DFT-based calculati...
DBCSR operations in CP2K.
subroutine, public copy_dbcsr_to_fm(matrix, fm)
Copy a DBCSR matrix to a BLACS matrix.
subroutine, public copy_fm_to_dbcsr_bc(fm, bc_mat)
Copy a BLACS matrix to a dbcsr matrix with a special block-cyclic distribution, which requires no com...
Utility routines to open and close files. Tracking of preconnections.
Definition cp_files.F:16
subroutine, public open_file(file_name, file_status, file_form, file_action, file_position, file_pad, unit_number, debug, skip_get_unit_number, file_access)
Opens the requested file using a free unit number.
Definition cp_files.F:308
represent the structure of a full matrix
subroutine, public cp_fm_struct_create(fmstruct, para_env, context, nrow_global, ncol_global, nrow_block, ncol_block, descriptor, first_p_pos, local_leading_dimension, template_fmstruct, square_blocks, force_block)
allocates and initializes a full matrix structure
subroutine, public cp_fm_struct_release(fmstruct)
releases a full matrix structure
represent a full matrix distributed on many processors
Definition cp_fm_types.F:15
subroutine, public cp_fm_copy_general(source, destination, para_env)
General copy of a fm matrix to another fm matrix. Uses non-blocking MPI rather than ScaLAPACK.
subroutine, public cp_fm_get_info(matrix, name, nrow_global, ncol_global, nrow_block, ncol_block, nrow_local, ncol_local, row_indices, col_indices, local_data, context, nrow_locals, ncol_locals, matrix_struct, para_env)
returns all kind of information about the full matrix
subroutine, public cp_fm_create(matrix, matrix_struct, name, use_sp)
creates a new full matrix with the given structure
various routines to log and control the output. The idea is that decisions about where to log should ...
subroutine, public cp_logger_set(logger, local_filename, global_filename)
sets various attributes of the given logger
subroutine, public cp_logger_create(logger, para_env, print_level, default_global_unit_nr, default_local_unit_nr, global_filename, local_filename, close_global_unit_on_dealloc, iter_info, close_local_unit_on_dealloc, suffix, template_logger)
initializes a logger
type(cp_logger_type) function, pointer, public cp_get_default_logger()
returns the default logger
routines to handle the output, The idea is to remove the decision of wheter to output and what to out...
integer function, public cp_print_key_unit_nr(logger, basis_section, print_key_path, extension, middle_name, local, log_filename, ignore_should_output, file_form, file_position, file_action, file_status, do_backup, on_file, is_new_file, mpi_io, fout)
...
subroutine, public cp_print_key_finished_output(unit_nr, logger, basis_section, print_key_path, local, ignore_should_output, on_file, mpi_io)
should be called after you finish working with a unit obtained with cp_print_key_unit_nr,...
subroutine, public init_input_type(input_settings, nsmax, rs_grid_section, ilevel, higher_grid_layout)
parses an input section to assign the proper values to the input type
types that represent a subsys, i.e. a part of the system
subroutine, public cp_subsys_get(subsys, ref_count, atomic_kinds, atomic_kind_set, particles, particle_set, local_particles, molecules, molecule_set, molecule_kinds, molecule_kind_set, local_molecules, para_env, colvar_p, shell_particles, core_particles, gci, multipoles, natom, nparticle, ncore, nshell, nkind, atprop, virial, results, cell)
returns information about various attributes of the given subsys
for a given dr()/dh(r) this will provide the bounds to be used if one wants to go over a sphere-subre...
Definition cube_utils.F:18
integer function, public return_cube_max_iradius(info)
...
Definition cube_utils.F:175
subroutine, public init_cube_info(info, dr, dh, dh_inv, ortho, max_radius)
...
Definition cube_utils.F:212
Routines to efficiently handle dense polynomial in 3 variables up to a given degree....
Definition d3_poly.F:23
subroutine, public init_d3_poly_module()
initialization of the cache, is called by functions in this module that use cached values
Definition d3_poly.F:74
Interface for the force calculations.
subroutine, public multiple_fe_list(force_env_sections, root_section, i_force_eval, nforce_eval)
returns the order of the multiple force_env
recursive subroutine, public force_env_get(force_env, in_use, fist_env, qs_env, meta_env, fp_env, subsys, para_env, potential_energy, additional_potential, kinetic_energy, harmonic_shell, kinetic_shell, cell, sub_force_env, qmmm_env, qmmmx_env, eip_env, pwdft_env, globenv, input, force_env_section, method_name_id, root_section, mixed_env, nnp_env, embed_env)
returns various attributes about the force environment
subroutine, public init_gaussian_gridlevel(gridlevel_info, ngrid_levels, cutoff, rel_cutoff, print_section)
...
Define type storing the global information of a run. Keep the amount of stored data small....
The types needed for the calculation of Hirshfeld charges and related functions.
subroutine, public create_hirshfeld_type(hirshfeld_env)
...
subroutine, public set_hirshfeld_info(hirshfeld_env, shape_function_type, iterative, ref_charge, fnorm, radius_type, use_bohr)
Set values of a Hirshfeld env.
subroutine, public release_hirshfeld_type(hirshfeld_env)
...
collects all constants needed in input so that they can be used without circular dependencies
integer, parameter, public mixed_cdft_serial
integer, parameter, public becke_cutoff_element
integer, parameter, public outer_scf_becke_constraint
integer, parameter, public outer_scf_hirshfeld_constraint
integer, parameter, public mixed_cdft_parallel
integer, parameter, public shape_function_gaussian
integer, parameter, public mixed_cdft_parallel_nobuild
objects that represent the structure of input sections and the data contained in an input section
recursive type(section_vals_type) function, pointer, public section_vals_get_subs_vals(section_vals, subsection_name, i_rep_section, can_return_null)
returns the values of the requested subsection
subroutine, public section_vals_get(section_vals, ref_count, n_repetition, n_subs_vals_rep, section, explicit)
returns various attributes about the section_vals
subroutine, public section_vals_duplicate(section_vals_in, section_vals_out, i_rep_start, i_rep_end)
creates a deep copy from section_vals_in to section_vals_out
subroutine, public section_vals_val_get(section_vals, keyword_name, i_rep_section, i_rep_val, n_rep_val, val, l_val, i_val, r_val, c_val, l_vals, i_vals, r_vals, c_vals, explicit)
returns the requested value
recursive subroutine, public section_vals_release(section_vals)
releases the given object
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
integer, parameter, public default_path_length
Definition kinds.F:58
Interface to the message passing library MPI.
Types for mixed CDFT calculations.
subroutine, public mixed_cdft_result_type_set(results, lowdin, wfn, nonortho, metric, rotation, h, s, wad, wda, w_diagonal, energy, strength, s_minushalf)
Updates arrays within the mixed CDFT result container.
subroutine, public mixed_cdft_result_type_release(results)
Releases all arrays within the mixed CDFT result container.
subroutine, public mixed_cdft_work_type_init(matrix)
Initializes the mixed_cdft_work_type.
Utility subroutines for mixed CDFT calculations.
subroutine, public map_permutation_to_states(n, ipermutation, i, j)
Given the size of a symmetric matrix and a permutation index, returns indices (i, j) of the off-diago...
subroutine, public mixed_cdft_init_structures(force_env, force_env_qs, mixed_env, mixed_cdft, settings)
Initialize all the structures needed for a mixed CDFT calculation.
subroutine, public mixed_cdft_transfer_settings(force_env, mixed_cdft, settings)
Transfer settings to mixed_cdft.
subroutine, public mixed_cdft_diagonalize_blocks(blocks, h_block, s_block, eigenvalues)
Diagonalizes each of the matrix blocks.
subroutine, public mixed_cdft_print_couplings(force_env)
Routine to print out the electronic coupling(s) between CDFT states.
subroutine, public mixed_cdft_read_block_diag(force_env, blocks, ignore_excited, nrecursion)
Read input section related to block diagonalization of the mixed CDFT Hamiltonian matrix.
subroutine, public mixed_cdft_redistribute_arrays(force_env)
Redistribute arrays needed for an ET coupling calculation from individual CDFT states to the mixed CD...
subroutine, public mixed_cdft_assemble_block_diag(mixed_cdft, blocks, h_block, eigenvalues, n, iounit)
Assembles the new block diagonalized mixed CDFT Hamiltonian and overlap matrices.
subroutine, public hfun_zero(fun, th, just_zero, bounds, work)
Determine confinement bounds along confinement dir (hardcoded to be z) and determine the number of no...
subroutine, public mixed_cdft_get_blocks(mixed_cdft, blocks, h_block, s_block)
Assembles the matrix blocks from the mixed CDFT Hamiltonian.
subroutine, public mixed_cdft_release_work(force_env)
Release storage reserved for mixed CDFT matrices.
subroutine, public mixed_cdft_parse_settings(force_env, mixed_env, mixed_cdft, settings, natom)
Parse settings for mixed cdft calculation and check their consistency.
subroutine, public get_mixed_env(mixed_env, atomic_kind_set, particle_set, local_particles, local_molecules, molecule_kind_set, molecule_set, cell, cell_ref, mixed_energy, para_env, sub_para_env, subsys, input, results, cdft_control)
Get the MIXED environment.
methods of pw_env that have dependence on qs_env
subroutine, public pw_env_create(pw_env)
creates a pw_env, if qs_env is given calls pw_env_rebuild
container for various plainwaves related things
subroutine, public pw_env_get(pw_env, pw_pools, cube_info, gridlevel_info, auxbas_pw_pool, auxbas_grid, auxbas_rs_desc, auxbas_rs_grid, rs_descs, rs_grids, xc_pw_pool, vdw_pw_pool, poisson_env, interp_section)
returns the various attributes of the pw env
integer, parameter, public halfspace
This module defines the grid data type and some basic operations on it.
Definition pw_grids.F:36
integer, parameter, public do_pw_grid_blocked_false
Definition pw_grids.F:78
subroutine, public pw_grid_release(pw_grid)
releases the given pw grid
Definition pw_grids.F:2133
subroutine, public pw_grid_setup(cell_hmat, pw_grid, grid_span, cutoff, bounds, bounds_local, npts, spherical, odd, fft_usage, ncommensurate, icommensurate, blocked, ref_grid, rs_dims, iounit)
sets up a pw_grid
Definition pw_grids.F:286
subroutine, public pw_grid_create(pw_grid, pe_group, local)
Initialize a PW grid with all defaults.
Definition pw_grids.F:93
Manages a pool of grids (to be used for example as tmp objects), but can also be used to instantiate ...
subroutine, public pw_pool_create(pool, pw_grid, max_cache)
creates a pool for pw
Defines CDFT control structures.
subroutine, public cdft_control_create(cdft_control)
create the cdft_control_type
subroutine, public get_qs_env(qs_env, atomic_kind_set, qs_kind_set, cell, super_cell, cell_ref, use_ref_cell, kpoints, dft_control, mos, sab_orb, sab_all, qmmm, qmmm_periodic, sac_ae, sac_ppl, sac_lri, sap_ppnl, sab_vdw, sab_scp, sap_oce, sab_lrc, sab_se, sab_xtbe, sab_tbe, sab_core, sab_xb, sab_xtb_nonbond, sab_almo, sab_kp, sab_kp_nosym, particle_set, energy, force, matrix_h, matrix_h_im, matrix_ks, matrix_ks_im, matrix_vxc, run_rtp, rtp, matrix_h_kp, matrix_h_im_kp, matrix_ks_kp, matrix_ks_im_kp, matrix_vxc_kp, kinetic_kp, matrix_s_kp, matrix_w_kp, matrix_s_ri_aux_kp, matrix_s, matrix_s_ri_aux, matrix_w, matrix_p_mp2, matrix_p_mp2_admm, rho, rho_xc, pw_env, ewald_env, ewald_pw, active_space, mpools, input, para_env, blacs_env, scf_control, rel_control, kinetic, qs_charges, vppl, rho_core, rho_nlcc, rho_nlcc_g, ks_env, ks_qmmm_env, wf_history, scf_env, local_particles, local_molecules, distribution_2d, dbcsr_dist, molecule_kind_set, molecule_set, subsys, cp_subsys, oce, local_rho_set, rho_atom_set, task_list, task_list_soft, rho0_atom_set, rho0_mpole, rhoz_set, ecoul_1c, rho0_s_rs, rho0_s_gs, do_kpoints, has_unit_metric, requires_mo_derivs, mo_derivs, mo_loc_history, nkind, natom, nelectron_total, nelectron_spin, efield, neighbor_list_id, linres_control, xas_env, virial, cp_ddapc_env, cp_ddapc_ewald, outer_scf_history, outer_scf_ihistory, x_data, et_coupling, dftb_potential, results, se_taper, se_store_int_env, se_nddo_mpole, se_nonbond_env, admm_env, lri_env, lri_density, exstate_env, ec_env, dispersion_env, gcp_env, vee, rho_external, external_vxc, mask, mp2_env, bs_env, kg_env, wanniercentres, atprop, ls_scf_env, do_transport, transport_env, v_hartree_rspace, s_mstruct_changed, rho_changed, potential_changed, forces_up_to_date, mscfg_env, almo_scf_env, gradient_history, variable_history, embed_pot, spin_embed_pot, polar_env, mos_last_converged, rhs)
Get the QUICKSTEP environment.
Define the quickstep kind type and their sub types.
subroutine, public create_qs_kind_set(qs_kind_set, atomic_kind_set, kind_section, para_env, force_env_section)
Read an atomic kind set data set from the input file.
subroutine, public rs_grid_print(rs, iounit)
Print information on grids to output.
subroutine, public rs_grid_create(rs, desc)
...
subroutine, public rs_grid_create_descriptor(desc, pw_grid, input_settings, border_points)
Determine the setup of real space grids - this is divided up into the creation of a descriptor and th...
Provides all information about an atomic kind.
Type defining parameters related to the simulation cell.
Definition cell_types.F:55
represent a pointer to a 1d array
represent a pointer to a 1d array
represent a pointer to a 2d array
represent a blacs multidimensional parallel environment (for the mpi corrispective see cp_paratypes/m...
keeps the information about the structure of a full matrix
represent a full matrix
type of a logger, at the moment it contains just a print level starting at which level it should be l...
represents a system: atoms, molecules, their pos,vel,...
wrapper to abstract the force evaluation of the various methods
contains the initially parsed file and the initial parallel environment
Container for constraint settings to check consistency of force_evals.
Main mixed CDFT control type.
contained for different pw related things
to create arrays of pools
Manages a pool of grids (to be used for example as tmp objects), but can also be used to instantiate ...
Provides all information about a quickstep kind.