(git:97501a3)
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-2025 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
32 USE cp_files, ONLY: open_file
52 USE cube_utils, ONLY: init_cube_info,&
76 USE kinds, ONLY: default_path_length,&
78 dp
89 USE pw_env_types, ONLY: pw_env_get,&
91 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%group%num_pe_cart
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_env_create(mixed_cdft%pw_env)
692 ! Decide what kind of layout to use and setup the grid
693 ! Processor mappings currently supported:
694 ! (2np,1) --> (np,1)
695 ! (nx,2ny) --> (nx,ny)
696 ! (nx,ny) --> (nx*ny/2,1) (required when xc_smooth is in use and with intermediate proc counts)
697 !
698 ! For cases 2 and 3, dlb redistributes YZ slices from overloaded processors to underloaded processors
699 ! For case 1, XZ slices are redistributed
700 ! TODO: Unify mappings. Now we essentially have separate code for cases 1-2 and 3.
701 ! This leads to very messy code especially with dlb turned on...
702 ! In terms of memory usage, it would be beneficial to replace case 1 with 3
703 ! and implement a similar arbitrary mapping to replace case 2
704
705 mixed_cdft%is_pencil = .false. ! Flag to control the first two mappings
706 mixed_cdft%is_special = .false. ! Flag to control the last mapping
707 ! With xc smoothing, the grid is always (ncpu/2,1) distributed
708 ! and correct behavior cannot be guaranteed for ncpu/2 > nx, so we abort...
709 IF (ncpu/2 .GT. settings%npts(1, 1)) &
710 cpabort("ncpu/2 => nx: decrease ncpu or disable xc_smoothing")
711 !
712 ALLOCATE (mixed_rs_dims(2))
713 IF (settings%rs_dims(2, 1) /= 1) mixed_cdft%is_pencil = .true.
714 IF (.NOT. mixed_cdft%is_pencil .AND. ncpu .GT. settings%npts(1, 1)) mixed_cdft%is_special = .true.
715 IF (mixed_cdft%is_special) THEN
716 mixed_rs_dims = (/-1, -1/)
717 ELSE IF (mixed_cdft%is_pencil) THEN
718 mixed_rs_dims = (/settings%rs_dims(1, 1), 2*settings%rs_dims(2, 1)/)
719 ELSE
720 mixed_rs_dims = (/2*settings%rs_dims(1, 1), 1/)
721 END IF
722 IF (.NOT. mixed_env%do_mixed_qmmm_cdft) THEN
723 CALL force_env_get(force_env=force_env, &
724 cell=cell_mix)
725 ELSE
726 CALL get_qs_env(force_env_qs%qmmm_env%qs_env, &
727 cell=cell_mix)
728 END IF
729 CALL pw_grid_create(pw_grid, force_env%para_env, cell_mix%hmat, grid_span=settings%grid_span(1), &
730 npts=settings%npts(:, 1), cutoff=settings%cutoff(1), &
731 spherical=settings%is_spherical, odd=settings%is_odd, &
732 fft_usage=.true., ncommensurate=0, icommensurate=1, &
733 blocked=do_pw_grid_blocked_false, rs_dims=mixed_rs_dims, &
734 iounit=iounit)
735 ! Check if the layout was successfully created
736 IF (mixed_cdft%is_special) THEN
737 IF (.NOT. pw_grid%para%group%num_pe_cart(2) /= 1) is_match = .false.
738 ELSE IF (mixed_cdft%is_pencil) THEN
739 IF (.NOT. pw_grid%para%group%num_pe_cart(1) == mixed_rs_dims(1)) is_match = .false.
740 ELSE
741 IF (.NOT. pw_grid%para%group%num_pe_cart(2) == 1) is_match = .false.
742 END IF
743 IF (.NOT. is_match) &
744 CALL cp_abort(__location__, &
745 "Unable to create a suitable grid distribution "// &
746 "for mixed CDFT calculations. Try decreasing the total number "// &
747 "of processors or disabling xc_smoothing.")
748 DEALLOCATE (mixed_rs_dims)
749 ! Create the pool
750 bo_mixed = pw_grid%bounds_local
751 ALLOCATE (pw_pools(1))
752 NULLIFY (pw_pools(1)%pool)
753 CALL pw_pool_create(pw_pools(1)%pool, pw_grid=pw_grid)
754 ! Initialize Gaussian cavity confinement
755 IF (mixed_cdft%cdft_control%becke_control%cavity_confine) THEN
756 CALL create_hirshfeld_type(mixed_cdft%cdft_control%becke_control%cavity_env)
757 CALL set_hirshfeld_info(mixed_cdft%cdft_control%becke_control%cavity_env, &
758 shape_function_type=shape_function_gaussian, iterative=.false., &
759 radius_type=mixed_cdft%cdft_control%becke_control%cavity_shape, &
760 use_bohr=mixed_cdft%cdft_control%becke_control%use_bohr)
761 END IF
762 ! Gaussian confinement/wavefunction overlap method needs qs_kind_set
763 ! Gaussian cavity confinement also needs the auxbas_rs_grid
764 IF (mixed_cdft%cdft_control%becke_control%cavity_confine .OR. &
765 mixed_cdft%wfn_overlap_method) THEN
766 print_section => section_vals_get_subs_vals(force_env_section, &
767 "PRINT%GRID_INFORMATION")
768 ALLOCATE (mixed_cdft%pw_env%gridlevel_info)
769 CALL init_gaussian_gridlevel(mixed_cdft%pw_env%gridlevel_info, &
770 ngrid_levels=1, cutoff=settings%cutoff, &
771 rel_cutoff=settings%rel_cutoff(1), &
772 print_section=print_section)
773 ALLOCATE (rs_descs(1))
774 ALLOCATE (rs_grids(1))
775 ALLOCATE (mixed_cdft%pw_env%cube_info(1))
776 higher_grid_layout = (/-1, -1, -1/)
778 CALL init_cube_info(mixed_cdft%pw_env%cube_info(1), &
779 pw_grid%dr(:), pw_grid%dh(:, :), &
780 pw_grid%dh_inv(:, :), &
781 pw_grid%orthorhombic, settings%radius)
782 NULLIFY (root_section, force_env_section, force_env_sections, rs_grid_section)
783 CALL force_env_get(force_env, root_section=root_section)
784 force_env_sections => section_vals_get_subs_vals(root_section, "FORCE_EVAL")
785 CALL multiple_fe_list(force_env_sections, root_section, i_force_eval, n_force_eval)
786 CALL section_vals_duplicate(force_env_sections, force_env_section, &
787 i_force_eval(2), i_force_eval(2))
788 rs_grid_section => section_vals_get_subs_vals(force_env_section, "DFT%MGRID%RS_GRID")
789 CALL init_input_type(input_settings, &
790 nsmax=2*max(1, return_cube_max_iradius(mixed_cdft%pw_env%cube_info(1))) + 1, &
791 rs_grid_section=rs_grid_section, ilevel=1, &
792 higher_grid_layout=higher_grid_layout)
793 NULLIFY (rs_descs(1)%rs_desc)
794 CALL rs_grid_create_descriptor(rs_descs(1)%rs_desc, pw_grid, input_settings)
795 IF (rs_descs(1)%rs_desc%distributed) higher_grid_layout = rs_descs(1)%rs_desc%group_dim
796 CALL rs_grid_create(rs_grids(1), rs_descs(1)%rs_desc)
797 CALL rs_grid_print(rs_grids(1), iounit)
798 mixed_cdft%pw_env%rs_descs => rs_descs
799 mixed_cdft%pw_env%rs_grids => rs_grids
800 ! qs_kind_set
801 subsys_section => section_vals_get_subs_vals(force_env_sections, "SUBSYS", &
802 i_rep_section=i_force_eval(1))
803 kind_section => section_vals_get_subs_vals(subsys_section, "KIND")
804 NULLIFY (qs_kind_set)
805 CALL cp_subsys_get(subsys_mix, atomic_kind_set=atomic_kind_set)
806 CALL create_qs_kind_set(qs_kind_set, atomic_kind_set, kind_section, &
807 force_env%para_env, force_env_section, silent=.false.)
808 mixed_cdft%qs_kind_set => qs_kind_set
809 DEALLOCATE (i_force_eval)
810 CALL section_vals_release(force_env_section)
811 END IF
812 CALL force_env_get(force_env=force_env, &
813 force_env_section=force_env_section)
814 CALL pw_grid_release(pw_grid)
815 mixed_cdft%pw_env%auxbas_grid = 1
816 NULLIFY (mixed_cdft%pw_env%pw_pools)
817 mixed_cdft%pw_env%pw_pools => pw_pools
818 bo = settings%bo
819 ! Determine which processors need to exchange data when redistributing the weight/gradient
820 IF (.NOT. mixed_cdft%is_special) THEN
821 ALLOCATE (mixed_cdft%dest_list(2))
822 ALLOCATE (mixed_cdft%source_list(2))
823 imap = force_env%para_env%mepos/2
824 mixed_cdft%dest_list = (/imap, imap + force_env%para_env%num_pe/2/)
825 imap = mod(force_env%para_env%mepos, force_env%para_env%num_pe/2) + &
826 modulo(force_env%para_env%mepos, force_env%para_env%num_pe/2)
827 mixed_cdft%source_list = (/imap, imap + 1/)
828 ! Determine bounds of the data that is replicated
829 ALLOCATE (mixed_cdft%recv_bo(4))
830 ALLOCATE (sendbuffer(2), recvbuffer(2), recvbuffer2(2))
831 IF (mixed_cdft%is_pencil) THEN
832 sendbuffer = (/bo_mixed(1, 2), bo_mixed(2, 2)/)
833 ELSE
834 sendbuffer = (/bo_mixed(1, 1), bo_mixed(2, 1)/)
835 END IF
836 ! Communicate bounds in steps
837 CALL force_env%para_env%isend(msgin=sendbuffer, dest=mixed_cdft%dest_list(1), &
838 request=req(1))
839 CALL force_env%para_env%irecv(msgout=recvbuffer, source=mixed_cdft%source_list(1), &
840 request=req(2))
841 CALL force_env%para_env%irecv(msgout=recvbuffer2, source=mixed_cdft%source_list(2), &
842 request=req(3))
843 CALL req(1)%wait()
844 CALL force_env%para_env%isend(msgin=sendbuffer, dest=mixed_cdft%dest_list(2), &
845 request=req(1))
846 CALL mp_waitall(req)
847 mixed_cdft%recv_bo(1:2) = recvbuffer
848 mixed_cdft%recv_bo(3:4) = recvbuffer2
849 DEALLOCATE (sendbuffer, recvbuffer, recvbuffer2)
850 ELSE
851 IF (mixed_env%do_mixed_qmmm_cdft) THEN
852 qs_env => force_env_qs%qmmm_env%qs_env
853 ELSE
854 CALL force_env_get(force_env_qs, qs_env=qs_env)
855 END IF
856 CALL get_qs_env(qs_env, pw_env=pw_env)
857 CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool)
858 ! work out the pw grid points each proc holds in the two (identical) parallel proc groups
859 ! note we only care about the x dir since we assume the y dir is not subdivided
860 ALLOCATE (bounds(0:auxbas_pw_pool%pw_grid%para%group%num_pe - 1, 1:2))
861 DO i = 0, auxbas_pw_pool%pw_grid%para%group%num_pe - 1
862 bounds(i, 1:2) = auxbas_pw_pool%pw_grid%para%bo(1:2, 1, i, 1)
863 bounds(i, 1:2) = bounds(i, 1:2) - auxbas_pw_pool%pw_grid%npts(1)/2 - 1
864 END DO
865 ! work out which procs to send my grid points
866 ! first get the number of target procs per group
867 ntargets = 0
868 offset = -1
869 DO i = 0, auxbas_pw_pool%pw_grid%para%group%num_pe - 1
870 IF ((bounds(i, 1) .GE. bo_mixed(1, 1) .AND. bounds(i, 1) .LE. bo_mixed(2, 1)) .OR. &
871 (bounds(i, 2) .GE. bo_mixed(1, 1) .AND. bounds(i, 2) .LE. bo_mixed(2, 1))) THEN
872 ntargets = ntargets + 1
873 IF (offset == -1) offset = i
874 ELSE IF (bounds(i, 2) .GT. bo_mixed(2, 1)) THEN
875 EXIT
876 ELSE
877 cycle
878 END IF
879 END DO
880 ALLOCATE (mixed_cdft%dest_list(ntargets))
881 ALLOCATE (mixed_cdft%dest_list_bo(2, ntargets))
882 ! now determine the actual grid points to send
883 j = 1
884 DO i = offset, offset + ntargets - 1
885 mixed_cdft%dest_list(j) = i
886 mixed_cdft%dest_list_bo(:, j) = (/bo_mixed(1, 1) + (bounds(i, 1) - bo_mixed(1, 1)), &
887 bo_mixed(2, 1) + (bounds(i, 2) - bo_mixed(2, 1))/)
888 j = j + 1
889 END DO
890 ALLOCATE (mixed_cdft%dest_list_save(ntargets), mixed_cdft%dest_bo_save(2, ntargets))
891 ! We need to store backups of these arrays since they might get reallocated during dlb
892 mixed_cdft%dest_list_save = mixed_cdft%dest_list
893 mixed_cdft%dest_bo_save = mixed_cdft%dest_list_bo
894 ! finally determine which procs will send me grid points
895 ! now we need info about y dir also
896 DEALLOCATE (bounds)
897 ALLOCATE (bounds(0:pw_pools(1)%pool%pw_grid%para%group%num_pe - 1, 1:4))
898 DO i = 0, pw_pools(1)%pool%pw_grid%para%group%num_pe - 1
899 bounds(i, 1:2) = pw_pools(1)%pool%pw_grid%para%bo(1:2, 1, i, 1)
900 bounds(i, 3:4) = pw_pools(1)%pool%pw_grid%para%bo(1:2, 2, i, 1)
901 bounds(i, 1:2) = bounds(i, 1:2) - pw_pools(1)%pool%pw_grid%npts(1)/2 - 1
902 bounds(i, 3:4) = bounds(i, 3:4) - pw_pools(1)%pool%pw_grid%npts(2)/2 - 1
903 END DO
904 ntargets = 0
905 offset = -1
906 DO i = 0, pw_pools(1)%pool%pw_grid%para%group%num_pe - 1
907 IF ((bo(1, 1) .GE. bounds(i, 1) .AND. bo(1, 1) .LE. bounds(i, 2)) .OR. &
908 (bo(2, 1) .GE. bounds(i, 1) .AND. bo(2, 1) .LE. bounds(i, 2))) THEN
909 ntargets = ntargets + 1
910 IF (offset == -1) offset = i
911 ELSE IF (bo(2, 1) .LT. bounds(i, 1)) THEN
912 EXIT
913 ELSE
914 cycle
915 END IF
916 END DO
917 ALLOCATE (mixed_cdft%source_list(ntargets))
918 ALLOCATE (mixed_cdft%source_list_bo(4, ntargets))
919 j = 1
920 DO i = offset, offset + ntargets - 1
921 mixed_cdft%source_list(j) = i
922 IF (bo(1, 1) .GE. bounds(i, 1) .AND. bo(2, 1) .LE. bounds(i, 2)) THEN
923 mixed_cdft%source_list_bo(:, j) = (/bo(1, 1), bo(2, 1), &
924 bounds(i, 3), bounds(i, 4)/)
925 ELSE IF (bo(1, 1) .GE. bounds(i, 1) .AND. bo(1, 1) .LE. bounds(i, 2)) THEN
926 mixed_cdft%source_list_bo(:, j) = (/bo(1, 1), bounds(i, 2), &
927 bounds(i, 3), bounds(i, 4)/)
928 ELSE
929 mixed_cdft%source_list_bo(:, j) = (/bounds(i, 1), bo(2, 1), &
930 bounds(i, 3), bounds(i, 4)/)
931 END IF
932 j = j + 1
933 END DO
934 ALLOCATE (mixed_cdft%source_list_save(ntargets), mixed_cdft%source_bo_save(4, ntargets))
935 ! We need to store backups of these arrays since they might get reallocated during dlb
936 mixed_cdft%source_list_save = mixed_cdft%source_list
937 mixed_cdft%source_bo_save = mixed_cdft%source_list_bo
938 DEALLOCATE (bounds)
939 END IF
940 ELSE
941 ! Create loggers to redirect the output of all CDFT states to different files
942 ! even when the states are treated in serial (the initial print of QS data [basis set etc] for
943 ! all states unfortunately goes to the first log file)
944 CALL force_env_get(force_env, root_section=root_section)
945 ALLOCATE (mixed_cdft%sub_logger(nforce_eval - 1))
946 DO i = 1, nforce_eval - 1
947 IF (force_env%para_env%is_source()) THEN
948 CALL section_vals_val_get(root_section, "GLOBAL%PROJECT_NAME", &
949 c_val=input_file_path)
950 lp = len_trim(input_file_path)
951 input_file_path(lp + 1:len(input_file_path)) = "-r-"//adjustl(cp_to_string(i + 1))
952 lp = len_trim(input_file_path)
953 output_file_path = input_file_path(1:lp)//".out"
954 CALL open_file(file_name=output_file_path, file_status="UNKNOWN", &
955 file_action="WRITE", file_position="APPEND", &
956 unit_number=unit_nr)
957 ELSE
958 unit_nr = -1
959 END IF
960 CALL cp_logger_create(mixed_cdft%sub_logger(i)%p, &
961 para_env=force_env%para_env, &
962 default_global_unit_nr=unit_nr, &
963 close_global_unit_on_dealloc=.false.)
964 ! Try to use better names for the local log if it is not too late
965 CALL section_vals_val_get(root_section, "GLOBAL%OUTPUT_FILE_NAME", &
966 c_val=c_val)
967 IF (c_val /= "") THEN
968 CALL cp_logger_set(mixed_cdft%sub_logger(i)%p, &
969 local_filename=trim(c_val)//"_localLog")
970 END IF
971 CALL section_vals_val_get(root_section, "GLOBAL%PROJECT", c_val=c_val)
972 IF (c_val /= "") THEN
973 CALL cp_logger_set(mixed_cdft%sub_logger(i)%p, &
974 local_filename=trim(c_val)//"_localLog")
975 END IF
976 IF (len_trim(c_val) > default_string_length) THEN
977 cpwarn("The mixed CDFT project name will be truncated.")
978 END IF
979 mixed_cdft%sub_logger(i)%p%iter_info%project_name = trim(c_val)
980 CALL section_vals_val_get(root_section, "GLOBAL%PRINT_LEVEL", &
981 i_val=mixed_cdft%sub_logger(i)%p%iter_info%print_level)
982 END DO
983 IF (mixed_cdft%wfn_overlap_method) THEN
984 ! qs_kind_set
985 NULLIFY (root_section, force_env_section, force_env_sections, rs_grid_section)
986 CALL force_env_get(force_env, root_section=root_section)
987 force_env_sections => section_vals_get_subs_vals(root_section, "FORCE_EVAL")
988 CALL multiple_fe_list(force_env_sections, root_section, i_force_eval, n_force_eval)
989 CALL section_vals_duplicate(force_env_sections, force_env_section, &
990 i_force_eval(2), i_force_eval(2))
991 subsys_section => section_vals_get_subs_vals(force_env_sections, "SUBSYS", &
992 i_rep_section=i_force_eval(1))
993 kind_section => section_vals_get_subs_vals(subsys_section, "KIND")
994 NULLIFY (qs_kind_set)
995 CALL cp_subsys_get(subsys_mix, atomic_kind_set=atomic_kind_set)
996 CALL create_qs_kind_set(qs_kind_set, atomic_kind_set, kind_section, &
997 force_env%para_env, force_env_section, silent=.false.)
998 mixed_cdft%qs_kind_set => qs_kind_set
999 DEALLOCATE (i_force_eval)
1000 CALL section_vals_release(force_env_section)
1001 mixed_cdft%qs_kind_set => qs_kind_set
1002 END IF
1003 CALL force_env_get(force_env=force_env, &
1004 force_env_section=force_env_section)
1005 END IF
1006 ! Deallocate settings temporaries
1007 DEALLOCATE (settings%grid_span)
1008 DEALLOCATE (settings%npts)
1009 DEALLOCATE (settings%spherical)
1010 DEALLOCATE (settings%rs_dims)
1011 DEALLOCATE (settings%odd)
1012 DEALLOCATE (settings%atoms)
1013 IF (mixed_cdft%run_type == mixed_cdft_parallel) &
1014 DEALLOCATE (settings%coeffs)
1015 DEALLOCATE (settings%cutoffs)
1016 DEALLOCATE (settings%radii)
1017 DEALLOCATE (settings%si)
1018 DEALLOCATE (settings%sr)
1019 DEALLOCATE (settings%sb)
1020 DEALLOCATE (settings%cutoff)
1021 DEALLOCATE (settings%rel_cutoff)
1022 ! Setup mixed blacs_env for redistributing arrays during ET coupling calculation
1023 IF (mixed_env%do_mixed_et) THEN
1024 NULLIFY (root_section)
1025 CALL force_env_get(force_env, globenv=globenv, root_section=root_section)
1026 CALL cp_blacs_env_create(mixed_cdft%blacs_env, force_env%para_env, globenv%blacs_grid_layout, &
1027 globenv%blacs_repeatable)
1028 END IF
1029 CALL cp_print_key_finished_output(iounit, logger, force_env_section, &
1030 "MIXED%MIXED_CDFT%PRINT%PROGRAM_RUN_INFO")
1031
1032 END SUBROUTINE mixed_cdft_init_structures
1033
1034! **************************************************************************************************
1035!> \brief Redistribute arrays needed for an ET coupling calculation from individual CDFT states to
1036!> the mixed CDFT env, that is, move the arrays to the correct blacs context. For parallel
1037!> simulations, the array processor distributions also change from N to 2N processors.
1038!> \param force_env the force_env that holds the CDFT states
1039!> \par History
1040!> 01.2017 created [Nico Holmberg]
1041! **************************************************************************************************
1043 TYPE(force_env_type), POINTER :: force_env
1044
1045 INTEGER :: iforce_eval, ispin, ivar, ncol_overlap, &
1046 ncol_wmat, nforce_eval, nrow_overlap, &
1047 nrow_wmat, nspins, nvar
1048 INTEGER, ALLOCATABLE, DIMENSION(:) :: ncol_mo, nrow_mo
1049 LOGICAL :: uniform_occupation
1050 LOGICAL, ALLOCATABLE, DIMENSION(:) :: has_occupation_numbers
1051 TYPE(cp_1d_r_p_type), ALLOCATABLE, DIMENSION(:, :) :: occno_tmp
1052 TYPE(cp_blacs_env_type), POINTER :: blacs_env
1053 TYPE(cp_fm_struct_type), POINTER :: fm_struct_mo, fm_struct_overlap, &
1054 fm_struct_tmp, fm_struct_wmat
1055 TYPE(cp_fm_type) :: matrix_s_tmp, mixed_matrix_s_tmp
1056 TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:, :) :: matrix_p_tmp, mixed_matrix_p_tmp, &
1057 mixed_wmat_tmp, mo_coeff_tmp, wmat_tmp
1058 TYPE(cp_fm_type), DIMENSION(:, :), POINTER :: mixed_mo_coeff
1059 TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: density_matrix, w_matrix
1060 TYPE(dbcsr_type) :: desymm_tmp
1061 TYPE(dbcsr_type), POINTER :: mixed_matrix_s
1062 TYPE(dft_control_type), POINTER :: dft_control
1063 TYPE(force_env_type), POINTER :: force_env_qs
1064 TYPE(mixed_cdft_type), POINTER :: mixed_cdft
1065 TYPE(mixed_environment_type), POINTER :: mixed_env
1066 TYPE(qs_environment_type), POINTER :: qs_env
1067
1068 NULLIFY (mixed_env, mixed_cdft, qs_env, dft_control, fm_struct_mo, &
1069 fm_struct_wmat, fm_struct_overlap, fm_struct_tmp, &
1070 mixed_mo_coeff, mixed_matrix_s, density_matrix, blacs_env, w_matrix, force_env_qs)
1071 cpassert(ASSOCIATED(force_env))
1072 mixed_env => force_env%mixed_env
1073 nforce_eval = SIZE(force_env%sub_force_env)
1074 CALL get_mixed_env(mixed_env, cdft_control=mixed_cdft)
1075 cpassert(ASSOCIATED(mixed_cdft))
1076 CALL mixed_cdft_work_type_init(mixed_cdft%matrix)
1077 ! Get nspins and query for non-uniform occupation numbers
1078 ALLOCATE (has_occupation_numbers(nforce_eval))
1079 has_occupation_numbers = .false.
1080 DO iforce_eval = 1, nforce_eval
1081 IF (.NOT. ASSOCIATED(force_env%sub_force_env(iforce_eval)%force_env)) cycle
1082 force_env_qs => force_env%sub_force_env(iforce_eval)%force_env
1083 IF (force_env%mixed_env%do_mixed_qmmm_cdft) THEN
1084 qs_env => force_env_qs%qmmm_env%qs_env
1085 ELSE
1086 CALL force_env_get(force_env_qs, qs_env=qs_env)
1087 END IF
1088 CALL get_qs_env(qs_env, dft_control=dft_control)
1089 cpassert(ASSOCIATED(dft_control))
1090 nspins = dft_control%nspins
1091 IF (force_env_qs%para_env%is_source()) &
1092 has_occupation_numbers(iforce_eval) = ALLOCATED(dft_control%qs_control%cdft_control%occupations)
1093 END DO
1094 CALL force_env%para_env%sum(has_occupation_numbers(1))
1095 DO iforce_eval = 2, nforce_eval
1096 CALL force_env%para_env%sum(has_occupation_numbers(iforce_eval))
1097 IF (has_occupation_numbers(1) .NEQV. has_occupation_numbers(iforce_eval)) &
1098 CALL cp_abort(__location__, &
1099 "Mixing of uniform and non-uniform occupations is not allowed.")
1100 END DO
1101 uniform_occupation = .NOT. has_occupation_numbers(1)
1102 DEALLOCATE (has_occupation_numbers)
1103 ! Get number of weight functions per state as well as the type of each constraint
1104 nvar = SIZE(dft_control%qs_control%cdft_control%target)
1105 IF (.NOT. ALLOCATED(mixed_cdft%constraint_type)) THEN
1106 ALLOCATE (mixed_cdft%constraint_type(nvar, nforce_eval))
1107 mixed_cdft%constraint_type(:, :) = 0
1108 IF (mixed_cdft%identical_constraints) THEN
1109 DO ivar = 1, nvar
1110 mixed_cdft%constraint_type(ivar, :) = &
1111 dft_control%qs_control%cdft_control%group(ivar)%constraint_type
1112 END DO
1113 ELSE
1114 ! Possibly couple spin and charge constraints
1115 DO iforce_eval = 1, nforce_eval
1116 IF (.NOT. ASSOCIATED(force_env%sub_force_env(iforce_eval)%force_env)) cycle
1117 IF (force_env%mixed_env%do_mixed_qmmm_cdft) THEN
1118 qs_env => force_env%sub_force_env(iforce_eval)%force_env%qmmm_env%qs_env
1119 ELSE
1120 CALL force_env_get(force_env%sub_force_env(iforce_eval)%force_env, qs_env=qs_env)
1121 END IF
1122 CALL get_qs_env(qs_env, dft_control=dft_control)
1123 IF (force_env%sub_force_env(iforce_eval)%force_env%para_env%is_source()) THEN
1124 DO ivar = 1, nvar
1125 mixed_cdft%constraint_type(ivar, iforce_eval) = &
1126 dft_control%qs_control%cdft_control%group(ivar)%constraint_type
1127 END DO
1128 END IF
1129 END DO
1130 CALL force_env%para_env%sum(mixed_cdft%constraint_type)
1131 END IF
1132 END IF
1133 ! Transfer data from sub_force_envs to temporaries
1134 ALLOCATE (mixed_cdft%matrix%mixed_mo_coeff(nforce_eval, nspins))
1135 mixed_mo_coeff => mixed_cdft%matrix%mixed_mo_coeff
1136 ALLOCATE (mixed_cdft%matrix%w_matrix(nforce_eval, nvar))
1137 w_matrix => mixed_cdft%matrix%w_matrix
1138 CALL dbcsr_init_p(mixed_cdft%matrix%mixed_matrix_s)
1139 mixed_matrix_s => mixed_cdft%matrix%mixed_matrix_s
1140 IF (mixed_cdft%calculate_metric) THEN
1141 ALLOCATE (mixed_cdft%matrix%density_matrix(nforce_eval, nspins))
1142 density_matrix => mixed_cdft%matrix%density_matrix
1143 END IF
1144 ALLOCATE (mo_coeff_tmp(nforce_eval, nspins), wmat_tmp(nforce_eval, nvar))
1145 ALLOCATE (nrow_mo(nspins), ncol_mo(nspins))
1146 IF (mixed_cdft%calculate_metric) ALLOCATE (matrix_p_tmp(nforce_eval, nspins))
1147 IF (.NOT. uniform_occupation) THEN
1148 ALLOCATE (mixed_cdft%occupations(nforce_eval, nspins))
1149 ALLOCATE (occno_tmp(nforce_eval, nspins))
1150 END IF
1151 DO iforce_eval = 1, nforce_eval
1152 ! Temporary arrays need to be nulled on every process
1153 DO ispin = 1, nspins
1154 ! Valgrind 3.12/gfortran 4.8.4 oddly complains here (unconditional jump)
1155 ! if mixed_cdft%calculate_metric = .FALSE. and the need to null the array
1156 ! is queried with IF (mixed_cdft%calculate_metric) &
1157 IF (.NOT. uniform_occupation) &
1158 NULLIFY (occno_tmp(iforce_eval, ispin)%array)
1159 END DO
1160 IF (.NOT. ASSOCIATED(force_env%sub_force_env(iforce_eval)%force_env)) cycle
1161 ! From this point onward, we access data local to the sub_force_envs
1162 ! Get qs_env
1163 force_env_qs => force_env%sub_force_env(iforce_eval)%force_env
1164 IF (force_env%mixed_env%do_mixed_qmmm_cdft) THEN
1165 qs_env => force_env_qs%qmmm_env%qs_env
1166 ELSE
1167 CALL force_env_get(force_env_qs, qs_env=qs_env)
1168 END IF
1169 CALL get_qs_env(qs_env, dft_control=dft_control, blacs_env=blacs_env)
1170 ! Store dimensions of the transferred arrays
1171 CALL dbcsr_get_info(dft_control%qs_control%cdft_control%matrix_s%matrix, &
1172 nfullrows_total=nrow_overlap, nfullcols_total=ncol_overlap)
1173 CALL dbcsr_get_info(dft_control%qs_control%cdft_control%wmat(1)%matrix, &
1174 nfullrows_total=nrow_wmat, nfullcols_total=ncol_wmat)
1175 ! MO Coefficients
1176 DO ispin = 1, nspins
1177 CALL cp_fm_get_info(dft_control%qs_control%cdft_control%mo_coeff(ispin), &
1178 ncol_global=ncol_mo(ispin), nrow_global=nrow_mo(ispin))
1179 CALL cp_fm_create(matrix=mo_coeff_tmp(iforce_eval, ispin), &
1180 matrix_struct=dft_control%qs_control%cdft_control%mo_coeff(ispin)%matrix_struct, &
1181 name="MO_COEFF_"//trim(adjustl(cp_to_string(iforce_eval)))//"_" &
1182 //trim(adjustl(cp_to_string(ispin)))//"_MATRIX")
1183 CALL cp_fm_to_fm(dft_control%qs_control%cdft_control%mo_coeff(ispin), &
1184 mo_coeff_tmp(iforce_eval, ispin))
1185 END DO
1186 CALL cp_fm_release(dft_control%qs_control%cdft_control%mo_coeff)
1187 ! Matrix representation(s) of the weight function(s) (dbcsr -> fm)
1188 CALL cp_fm_struct_create(fm_struct_tmp, nrow_global=nrow_wmat, ncol_global=ncol_wmat, context=blacs_env, &
1189 para_env=force_env%sub_force_env(iforce_eval)%force_env%para_env, &
1190 square_blocks=.true.)
1191 DO ivar = 1, nvar
1192 CALL cp_fm_create(wmat_tmp(iforce_eval, ivar), fm_struct_tmp, name="w_matrix")
1193 CALL dbcsr_desymmetrize(dft_control%qs_control%cdft_control%wmat(ivar)%matrix, desymm_tmp)
1194 CALL copy_dbcsr_to_fm(desymm_tmp, wmat_tmp(iforce_eval, ivar))
1195 CALL dbcsr_release(desymm_tmp)
1196 CALL dbcsr_release_p(dft_control%qs_control%cdft_control%wmat(ivar)%matrix)
1197 END DO
1198 DEALLOCATE (dft_control%qs_control%cdft_control%wmat)
1199 CALL cp_fm_struct_release(fm_struct_tmp)
1200 ! Overlap matrix is the same for all sub_force_envs, so we just copy the first one (dbcsr -> fm)
1201 IF (iforce_eval == 1) THEN
1202 CALL cp_fm_struct_create(fm_struct_tmp, nrow_global=nrow_overlap, &
1203 ncol_global=ncol_overlap, context=blacs_env, &
1204 para_env=force_env%sub_force_env(iforce_eval)%force_env%para_env)
1205 CALL cp_fm_create(matrix_s_tmp, fm_struct_tmp, name="s_matrix")
1206 CALL cp_fm_struct_release(fm_struct_tmp)
1207 CALL dbcsr_desymmetrize(dft_control%qs_control%cdft_control%matrix_s%matrix, desymm_tmp)
1208 CALL copy_dbcsr_to_fm(desymm_tmp, matrix_s_tmp)
1209 CALL dbcsr_release(desymm_tmp)
1210 END IF
1211 CALL dbcsr_release_p(dft_control%qs_control%cdft_control%matrix_s%matrix)
1212 ! Density_matrix (dbcsr -> fm)
1213 IF (mixed_cdft%calculate_metric) THEN
1214 DO ispin = 1, nspins
1215 ! Size AOxAO
1216 CALL cp_fm_struct_create(fm_struct_tmp, nrow_global=ncol_overlap, &
1217 ncol_global=ncol_overlap, context=blacs_env, &
1218 para_env=force_env%sub_force_env(iforce_eval)%force_env%para_env)
1219 CALL cp_fm_create(matrix_p_tmp(iforce_eval, ispin), fm_struct_tmp, name="dm_matrix")
1220 CALL cp_fm_struct_release(fm_struct_tmp)
1221 CALL dbcsr_desymmetrize(dft_control%qs_control%cdft_control%matrix_p(ispin)%matrix, desymm_tmp)
1222 CALL copy_dbcsr_to_fm(desymm_tmp, matrix_p_tmp(iforce_eval, ispin))
1223 CALL dbcsr_release(desymm_tmp)
1224 CALL dbcsr_release_p(dft_control%qs_control%cdft_control%matrix_p(ispin)%matrix)
1225 END DO
1226 DEALLOCATE (dft_control%qs_control%cdft_control%matrix_p)
1227 END IF
1228 ! Occupation numbers
1229 IF (.NOT. uniform_occupation) THEN
1230 DO ispin = 1, nspins
1231 IF (ncol_mo(ispin) /= SIZE(dft_control%qs_control%cdft_control%occupations(ispin)%array)) &
1232 cpabort("Array dimensions dont match.")
1233 IF (force_env_qs%para_env%is_source()) THEN
1234 ALLOCATE (occno_tmp(iforce_eval, ispin)%array(ncol_mo(ispin)))
1235 occno_tmp(iforce_eval, ispin)%array = dft_control%qs_control%cdft_control%occupations(ispin)%array
1236 END IF
1237 DEALLOCATE (dft_control%qs_control%cdft_control%occupations(ispin)%array)
1238 END DO
1239 DEALLOCATE (dft_control%qs_control%cdft_control%occupations)
1240 END IF
1241 END DO
1242 ! Create needed fm structs
1243 CALL cp_fm_struct_create(fm_struct_wmat, nrow_global=nrow_wmat, ncol_global=ncol_wmat, &
1244 context=mixed_cdft%blacs_env, para_env=force_env%para_env)
1245 CALL cp_fm_struct_create(fm_struct_overlap, nrow_global=nrow_overlap, ncol_global=ncol_overlap, &
1246 context=mixed_cdft%blacs_env, para_env=force_env%para_env)
1247 ! Redistribute arrays with copy_general (this is not optimal for dbcsr matrices but...)
1248 ! We use this method for the serial case (mixed_cdft%run_type == mixed_cdft_serial) as well to move the arrays to the
1249 ! correct blacs_env, which is impossible using a simple copy of the arrays
1250 ALLOCATE (mixed_wmat_tmp(nforce_eval, nvar))
1251 IF (mixed_cdft%calculate_metric) &
1252 ALLOCATE (mixed_matrix_p_tmp(nforce_eval, nspins))
1253 DO iforce_eval = 1, nforce_eval
1254 ! MO coefficients
1255 DO ispin = 1, nspins
1256 NULLIFY (fm_struct_mo)
1257 CALL cp_fm_struct_create(fm_struct_mo, nrow_global=nrow_mo(ispin), ncol_global=ncol_mo(ispin), &
1258 context=mixed_cdft%blacs_env, para_env=force_env%para_env)
1259 CALL cp_fm_create(matrix=mixed_mo_coeff(iforce_eval, ispin), &
1260 matrix_struct=fm_struct_mo, &
1261 name="MO_COEFF_"//trim(adjustl(cp_to_string(iforce_eval)))//"_" &
1262 //trim(adjustl(cp_to_string(ispin)))//"_MATRIX")
1263 CALL cp_fm_copy_general(mo_coeff_tmp(iforce_eval, ispin), &
1264 mixed_mo_coeff(iforce_eval, ispin), &
1265 mixed_cdft%blacs_env%para_env)
1266 CALL cp_fm_release(mo_coeff_tmp(iforce_eval, ispin))
1267 CALL cp_fm_struct_release(fm_struct_mo)
1268 END DO
1269 ! Weight
1270 DO ivar = 1, nvar
1271 NULLIFY (w_matrix(iforce_eval, ivar)%matrix)
1272 CALL dbcsr_init_p(w_matrix(iforce_eval, ivar)%matrix)
1273 CALL cp_fm_create(matrix=mixed_wmat_tmp(iforce_eval, ivar), &
1274 matrix_struct=fm_struct_wmat, &
1275 name="WEIGHT_"//trim(adjustl(cp_to_string(iforce_eval)))//"_MATRIX")
1276 CALL cp_fm_copy_general(wmat_tmp(iforce_eval, ivar), &
1277 mixed_wmat_tmp(iforce_eval, ivar), &
1278 mixed_cdft%blacs_env%para_env)
1279 CALL cp_fm_release(wmat_tmp(iforce_eval, ivar))
1280 ! (fm -> dbcsr)
1281 CALL copy_fm_to_dbcsr_bc(mixed_wmat_tmp(iforce_eval, ivar), &
1282 w_matrix(iforce_eval, ivar)%matrix)
1283 CALL cp_fm_release(mixed_wmat_tmp(iforce_eval, ivar))
1284 END DO
1285 ! Density matrix (fm -> dbcsr)
1286 IF (mixed_cdft%calculate_metric) THEN
1287 DO ispin = 1, nspins
1288 NULLIFY (density_matrix(iforce_eval, ispin)%matrix)
1289 CALL dbcsr_init_p(density_matrix(iforce_eval, ispin)%matrix)
1290 CALL cp_fm_create(matrix=mixed_matrix_p_tmp(iforce_eval, ispin), &
1291 matrix_struct=fm_struct_overlap, &
1292 name="DENSITY_"//trim(adjustl(cp_to_string(iforce_eval)))//"_"// &
1293 trim(adjustl(cp_to_string(ispin)))//"_MATRIX")
1294 CALL cp_fm_copy_general(matrix_p_tmp(iforce_eval, ispin), &
1295 mixed_matrix_p_tmp(iforce_eval, ispin), &
1296 mixed_cdft%blacs_env%para_env)
1297 CALL cp_fm_release(matrix_p_tmp(iforce_eval, ispin))
1298 CALL copy_fm_to_dbcsr_bc(mixed_matrix_p_tmp(iforce_eval, ispin), &
1299 density_matrix(iforce_eval, ispin)%matrix)
1300 CALL cp_fm_release(mixed_matrix_p_tmp(iforce_eval, ispin))
1301 END DO
1302 END IF
1303 END DO
1304 CALL cp_fm_struct_release(fm_struct_wmat)
1305 DEALLOCATE (mo_coeff_tmp, wmat_tmp, mixed_wmat_tmp)
1306 IF (mixed_cdft%calculate_metric) THEN
1307 DEALLOCATE (matrix_p_tmp)
1308 DEALLOCATE (mixed_matrix_p_tmp)
1309 END IF
1310 ! Overlap (fm -> dbcsr)
1311 CALL cp_fm_create(matrix=mixed_matrix_s_tmp, &
1312 matrix_struct=fm_struct_overlap, &
1313 name="OVERLAP_MATRIX")
1314 CALL cp_fm_struct_release(fm_struct_overlap)
1315 CALL cp_fm_copy_general(matrix_s_tmp, &
1316 mixed_matrix_s_tmp, &
1317 mixed_cdft%blacs_env%para_env)
1318 CALL cp_fm_release(matrix_s_tmp)
1319 CALL copy_fm_to_dbcsr_bc(mixed_matrix_s_tmp, mixed_matrix_s)
1320 CALL cp_fm_release(mixed_matrix_s_tmp)
1321 ! Occupation numbers
1322 IF (.NOT. uniform_occupation) THEN
1323 DO iforce_eval = 1, nforce_eval
1324 DO ispin = 1, nspins
1325 ALLOCATE (mixed_cdft%occupations(iforce_eval, ispin)%array(ncol_mo(ispin)))
1326 mixed_cdft%occupations(iforce_eval, ispin)%array = 0.0_dp
1327 IF (ASSOCIATED(occno_tmp(iforce_eval, ispin)%array)) THEN
1328 mixed_cdft%occupations(iforce_eval, ispin)%array = occno_tmp(iforce_eval, ispin)%array
1329 DEALLOCATE (occno_tmp(iforce_eval, ispin)%array)
1330 END IF
1331 CALL force_env%para_env%sum(mixed_cdft%occupations(iforce_eval, ispin)%array)
1332 END DO
1333 END DO
1334 DEALLOCATE (occno_tmp)
1335 END IF
1336 DEALLOCATE (ncol_mo, nrow_mo)
1337
1338 END SUBROUTINE mixed_cdft_redistribute_arrays
1339! **************************************************************************************************
1340!> \brief Routine to print out the electronic coupling(s) between CDFT states.
1341!> \param force_env the force_env that holds the CDFT states
1342!> \par History
1343!> 11.17 created [Nico Holmberg]
1344! **************************************************************************************************
1345 SUBROUTINE mixed_cdft_print_couplings(force_env)
1346 TYPE(force_env_type), POINTER :: force_env
1347
1348 INTEGER :: iounit, ipermutation, istate, ivar, &
1349 jstate, nforce_eval, npermutations, &
1350 nvar
1351 TYPE(cp_logger_type), POINTER :: logger
1352 TYPE(mixed_cdft_type), POINTER :: mixed_cdft
1353 TYPE(section_vals_type), POINTER :: force_env_section, print_section
1354
1355 NULLIFY (print_section, mixed_cdft)
1356
1357 logger => cp_get_default_logger()
1358 cpassert(ASSOCIATED(force_env))
1359 CALL force_env_get(force_env=force_env, &
1360 force_env_section=force_env_section)
1361 CALL get_mixed_env(force_env%mixed_env, cdft_control=mixed_cdft)
1362 cpassert(ASSOCIATED(mixed_cdft))
1363 print_section => section_vals_get_subs_vals(force_env_section, "MIXED%MIXED_CDFT%PRINT%PROGRAM_RUN_INFO")
1364 iounit = cp_print_key_unit_nr(logger, print_section, '', extension='.mixedLog')
1365 !
1366 cpassert(ALLOCATED(mixed_cdft%results%strength))
1367 cpassert(ALLOCATED(mixed_cdft%results%W_diagonal))
1368 cpassert(ALLOCATED(mixed_cdft%results%S))
1369 cpassert(ALLOCATED(mixed_cdft%results%energy))
1370 nforce_eval = SIZE(force_env%sub_force_env)
1371 nvar = SIZE(mixed_cdft%results%strength, 1)
1372 npermutations = nforce_eval*(nforce_eval - 1)/2 ! Size of upper triangular part
1373 IF (iounit > 0) THEN
1374 WRITE (iounit, '(/,T3,A,T66)') &
1375 '------------------------- CDFT coupling information --------------------------'
1376 WRITE (iounit, '(T3,A,T66,(3X,F12.2))') &
1377 'Information at step (fs):', mixed_cdft%sim_step*mixed_cdft%sim_dt
1378 DO ipermutation = 1, npermutations
1379 CALL map_permutation_to_states(nforce_eval, ipermutation, istate, jstate)
1380 WRITE (iounit, '(/,T3,A)') repeat('#', 44)
1381 WRITE (iounit, '(T3,A,I3,A,I3,A)') '###### CDFT states I =', istate, ' and J = ', jstate, ' ######'
1382 WRITE (iounit, '(T3,A)') repeat('#', 44)
1383 DO ivar = 1, nvar
1384 IF (ivar > 1) &
1385 WRITE (iounit, '(A)') ''
1386 WRITE (iounit, '(T3,A,T60,(3X,I18))') 'Atomic group:', ivar
1387 WRITE (iounit, '(T3,A,T60,(3X,F18.12))') &
1388 'Strength of constraint I:', mixed_cdft%results%strength(ivar, istate)
1389 WRITE (iounit, '(T3,A,T60,(3X,F18.12))') &
1390 'Strength of constraint J:', mixed_cdft%results%strength(ivar, jstate)
1391 WRITE (iounit, '(T3,A,T60,(3X,F18.12))') &
1392 'Final value of constraint I:', mixed_cdft%results%W_diagonal(ivar, istate)
1393 WRITE (iounit, '(T3,A,T60,(3X,F18.12))') &
1394 'Final value of constraint J:', mixed_cdft%results%W_diagonal(ivar, jstate)
1395 END DO
1396 WRITE (iounit, '(/,T3,A,T60,(3X,F18.12))') &
1397 'Overlap between states I and J:', mixed_cdft%results%S(istate, jstate)
1398 WRITE (iounit, '(T3,A,T60,(3X,F18.12))') &
1399 'Charge transfer energy (J-I) (Hartree):', (mixed_cdft%results%energy(jstate) - mixed_cdft%results%energy(istate))
1400 WRITE (iounit, *)
1401 IF (ALLOCATED(mixed_cdft%results%rotation)) THEN
1402 IF (abs(mixed_cdft%results%rotation(ipermutation))*1.0e3_dp .GE. 0.1_dp) THEN
1403 WRITE (iounit, '(T3,A,T60,(3X,F18.12))') &
1404 'Diabatic electronic coupling (rotation, mHartree):', &
1405 abs(mixed_cdft%results%rotation(ipermutation)*1.0e3_dp)
1406 ELSE
1407 WRITE (iounit, '(T3,A,T60,(3X,F18.12))') &
1408 'Diabatic electronic coupling (rotation, microHartree):', &
1409 abs(mixed_cdft%results%rotation(ipermutation)*1.0e6_dp)
1410 END IF
1411 END IF
1412 IF (ALLOCATED(mixed_cdft%results%lowdin)) THEN
1413 IF (abs(mixed_cdft%results%lowdin(ipermutation))*1.0e3_dp .GE. 0.1_dp) THEN
1414 WRITE (iounit, '(T3,A,T60,(3X,F18.12))') &
1415 'Diabatic electronic coupling (Lowdin, mHartree):', &
1416 abs(mixed_cdft%results%lowdin(ipermutation)*1.0e3_dp)
1417 ELSE
1418 WRITE (iounit, '(T3,A,T60,(3X,F18.12))') &
1419 'Diabatic electronic coupling (Lowdin, microHartree):', &
1420 abs(mixed_cdft%results%lowdin(ipermutation)*1.0e6_dp)
1421 END IF
1422 END IF
1423 IF (ALLOCATED(mixed_cdft%results%wfn)) THEN
1424 IF (mixed_cdft%results%wfn(ipermutation)*1.0e3_dp .GE. 0.1_dp) THEN
1425 WRITE (iounit, '(T3,A,T60,(3X,F18.12))') &
1426 'Diabatic electronic coupling (wfn overlap, mHartree):', &
1427 abs(mixed_cdft%results%wfn(ipermutation)*1.0e3_dp)
1428 ELSE
1429 WRITE (iounit, '(T3,A,T60,(3X,F18.12))') &
1430 'Diabatic electronic coupling (wfn overlap, microHartree):', &
1431 abs(mixed_cdft%results%wfn(ipermutation)*1.0e6_dp)
1432 END IF
1433 END IF
1434 IF (ALLOCATED(mixed_cdft%results%nonortho)) THEN
1435 WRITE (iounit, '(T3,A,T60,(3X,F18.12))') &
1436 'Diabatic electronic coupling (nonorthogonal, Hartree):', mixed_cdft%results%nonortho(ipermutation)
1437 END IF
1438 IF (ALLOCATED(mixed_cdft%results%metric)) THEN
1439 WRITE (iounit, *)
1440 IF (SIZE(mixed_cdft%results%metric, 2) == 1) THEN
1441 WRITE (iounit, '(T3,A,T66,(3X,F12.6))') &
1442 'Coupling reliability metric (0 is ideal):', mixed_cdft%results%metric(ipermutation, 1)
1443 ELSE
1444 WRITE (iounit, '(T3,A,T54,(3X,2F12.6))') &
1445 'Coupling reliability metric (0 is ideal):', &
1446 mixed_cdft%results%metric(ipermutation, 1), mixed_cdft%results%metric(ipermutation, 2)
1447 END IF
1448 END IF
1449 END DO
1450 WRITE (iounit, '(T3,A)') &
1451 '------------------------------------------------------------------------------'
1452 END IF
1453 CALL cp_print_key_finished_output(iounit, logger, force_env_section, &
1454 "MIXED%MIXED_CDFT%PRINT%PROGRAM_RUN_INFO")
1455
1456 END SUBROUTINE mixed_cdft_print_couplings
1457
1458! **************************************************************************************************
1459!> \brief Release storage reserved for mixed CDFT matrices
1460!> \param force_env the force_env that holds the CDFT states
1461!> \par History
1462!> 11.17 created [Nico Holmberg]
1463! **************************************************************************************************
1464 SUBROUTINE mixed_cdft_release_work(force_env)
1465 TYPE(force_env_type), POINTER :: force_env
1466
1467 TYPE(mixed_cdft_type), POINTER :: mixed_cdft
1468
1469 NULLIFY (mixed_cdft)
1470
1471 cpassert(ASSOCIATED(force_env))
1472 CALL get_mixed_env(force_env%mixed_env, cdft_control=mixed_cdft)
1473 cpassert(ASSOCIATED(mixed_cdft))
1474 CALL mixed_cdft_result_type_release(mixed_cdft%results)
1475
1476 END SUBROUTINE mixed_cdft_release_work
1477
1478! **************************************************************************************************
1479!> \brief Given the size of a symmetric matrix and a permutation index, returns indices (i, j) of the
1480!> off-diagonal element that corresponds to the permutation index. Assumes that the permutation
1481!> index was computed by going through the upper triangular part of the input matrix row-by-row.
1482!> \param n the size of the symmetric matrix
1483!> \param ipermutation the permutation index
1484!> \param i the row index corresponding to ipermutation
1485!> \param j the column index corresponding to ipermutation
1486! **************************************************************************************************
1487 SUBROUTINE map_permutation_to_states(n, ipermutation, i, j)
1488 INTEGER, INTENT(IN) :: n, ipermutation
1489 INTEGER, INTENT(OUT) :: i, j
1490
1491 INTEGER :: kcol, kpermutation, krow, npermutations
1492
1493 npermutations = n*(n - 1)/2 ! Size of upper triangular part
1494 IF (ipermutation > npermutations) &
1495 cpabort("Permutation index out of bounds")
1496 kpermutation = 0
1497 DO krow = 1, n
1498 DO kcol = krow + 1, n
1499 kpermutation = kpermutation + 1
1500 IF (kpermutation == ipermutation) THEN
1501 i = krow
1502 j = kcol
1503 RETURN
1504 END IF
1505 END DO
1506 END DO
1507
1508 END SUBROUTINE map_permutation_to_states
1509
1510! **************************************************************************************************
1511!> \brief Determine confinement bounds along confinement dir (hardcoded to be z)
1512!> and determine the number of nonzero entries
1513!> Optionally zero entries below a given threshold
1514!> \param fun input 3D potential (real space)
1515!> \param th threshold for screening values
1516!> \param just_zero determines if fun should only be zeroed without returning bounds/work
1517!> \param bounds the confinement bounds: fun is nonzero only between these values along 3rd dimension
1518!> \param work an estimate of the total number of grid points where fun is nonzero
1519! **************************************************************************************************
1520 SUBROUTINE hfun_zero(fun, th, just_zero, bounds, work)
1521 REAL(kind=dp), DIMENSION(:, :, :), INTENT(INOUT) :: fun
1522 REAL(kind=dp), INTENT(IN) :: th
1523 LOGICAL :: just_zero
1524 INTEGER, OPTIONAL :: bounds(2), work
1525
1526 INTEGER :: i1, i2, i3, lb, n1, n2, n3, nzeroed, &
1527 nzeroed_total, ub
1528 LOGICAL :: lb_final, ub_final
1529
1530 n1 = SIZE(fun, 1)
1531 n2 = SIZE(fun, 2)
1532 n3 = SIZE(fun, 3)
1533 nzeroed_total = 0
1534 IF (.NOT. just_zero) THEN
1535 cpassert(PRESENT(bounds))
1536 cpassert(PRESENT(work))
1537 lb = 1
1538 lb_final = .false.
1539 ub_final = .false.
1540 END IF
1541 DO i3 = 1, n3
1542 IF (.NOT. just_zero) nzeroed = 0
1543 DO i2 = 1, n2
1544 DO i1 = 1, n1
1545 IF (fun(i1, i2, i3) < th) THEN
1546 IF (.NOT. just_zero) THEN
1547 nzeroed = nzeroed + 1
1548 nzeroed_total = nzeroed_total + 1
1549 ELSE
1550 fun(i1, i2, i3) = 0.0_dp
1551 END IF
1552 END IF
1553 END DO
1554 END DO
1555 IF (.NOT. just_zero) THEN
1556 IF (nzeroed == (n2*n1)) THEN
1557 IF (.NOT. lb_final) THEN
1558 lb = i3
1559 ELSE IF (.NOT. ub_final) THEN
1560 ub = i3
1561 ub_final = .true.
1562 END IF
1563 ELSE
1564 IF (.NOT. lb_final) lb_final = .true.
1565 IF (ub_final) ub_final = .false. ! Safeguard against "holes"
1566 END IF
1567 END IF
1568 END DO
1569 IF (.NOT. just_zero) THEN
1570 IF (.NOT. ub_final) ub = n3
1571 bounds(1) = lb
1572 bounds(2) = ub
1573 bounds = bounds - (n3/2) - 1
1574 work = n3*n2*n1 - nzeroed_total
1575 END IF
1576
1577 END SUBROUTINE hfun_zero
1578
1579! **************************************************************************************************
1580!> \brief Read input section related to block diagonalization of the mixed CDFT Hamiltonian matrix.
1581!> \param force_env the force_env that holds the CDFT states
1582!> \param blocks list of CDFT states defining the matrix blocks
1583!> \param ignore_excited flag that determines if excited states resulting from the block
1584!> diagonalization process should be ignored
1585!> \param nrecursion integer that determines how many steps of recursive block diagonalization
1586!> is performed (1 if disabled)
1587!> \par History
1588!> 01.18 created [Nico Holmberg]
1589! **************************************************************************************************
1590 SUBROUTINE mixed_cdft_read_block_diag(force_env, blocks, ignore_excited, nrecursion)
1591 TYPE(force_env_type), POINTER :: force_env
1592 TYPE(cp_1d_i_p_type), ALLOCATABLE, DIMENSION(:), &
1593 INTENT(OUT) :: blocks
1594 LOGICAL, INTENT(OUT) :: ignore_excited
1595 INTEGER, INTENT(OUT) :: nrecursion
1596
1597 INTEGER :: i, j, k, l, nblk, nforce_eval
1598 INTEGER, DIMENSION(:), POINTER :: tmplist
1599 LOGICAL :: do_recursive, explicit, has_duplicates
1600 TYPE(section_vals_type), POINTER :: block_section, force_env_section
1601
1602 EXTERNAL :: dsygv
1603
1604 NULLIFY (force_env_section, block_section)
1605 cpassert(ASSOCIATED(force_env))
1606 nforce_eval = SIZE(force_env%sub_force_env)
1607
1608 CALL force_env_get(force_env=force_env, &
1609 force_env_section=force_env_section)
1610 block_section => section_vals_get_subs_vals(force_env_section, "MIXED%MIXED_CDFT%BLOCK_DIAGONALIZE")
1611
1612 CALL section_vals_get(block_section, explicit=explicit)
1613 IF (.NOT. explicit) &
1614 CALL cp_abort(__location__, &
1615 "Block diagonalization of CDFT Hamiltonian was requested, but the "// &
1616 "corresponding input section is missing!")
1617
1618 CALL section_vals_val_get(block_section, "BLOCK", n_rep_val=nblk)
1619 ALLOCATE (blocks(nblk))
1620 DO i = 1, nblk
1621 NULLIFY (blocks(i)%array)
1622 CALL section_vals_val_get(block_section, "BLOCK", i_rep_val=i, i_vals=tmplist)
1623 IF (SIZE(tmplist) < 1) &
1624 cpabort("Each BLOCK must contain at least 1 state.")
1625 ALLOCATE (blocks(i)%array(SIZE(tmplist)))
1626 blocks(i)%array(:) = tmplist(:)
1627 END DO
1628 CALL section_vals_val_get(block_section, "IGNORE_EXCITED", l_val=ignore_excited)
1629 CALL section_vals_val_get(block_section, "RECURSIVE_DIAGONALIZATION", l_val=do_recursive)
1630 ! Check that the requested states exist
1631 DO i = 1, nblk
1632 DO j = 1, SIZE(blocks(i)%array)
1633 IF (blocks(i)%array(j) < 1 .OR. blocks(i)%array(j) > nforce_eval) &
1634 cpabort("Requested state does not exist.")
1635 END DO
1636 END DO
1637 ! Check for duplicates
1638 has_duplicates = .false.
1639 DO i = 1, nblk
1640 ! Within same block
1641 DO j = 1, SIZE(blocks(i)%array)
1642 DO k = j + 1, SIZE(blocks(i)%array)
1643 IF (blocks(i)%array(j) == blocks(i)%array(k)) has_duplicates = .true.
1644 END DO
1645 END DO
1646 ! Within different blocks
1647 DO j = i + 1, nblk
1648 DO k = 1, SIZE(blocks(i)%array)
1649 DO l = 1, SIZE(blocks(j)%array)
1650 IF (blocks(i)%array(k) == blocks(j)%array(l)) has_duplicates = .true.
1651 END DO
1652 END DO
1653 END DO
1654 END DO
1655 IF (has_duplicates) cpabort("Duplicate states are not allowed.")
1656 nrecursion = 1
1657 IF (do_recursive) THEN
1658 IF (modulo(nblk, 2) /= 0) THEN
1659 CALL cp_warn(__location__, &
1660 "Number of blocks not divisible with 2. Recursive diagonalization not possible. "// &
1661 "Calculation proceeds without.")
1662 nrecursion = 1
1663 ELSE
1664 nrecursion = nblk/2
1665 END IF
1666 IF (nrecursion /= 1 .AND. .NOT. ignore_excited) &
1667 CALL cp_abort(__location__, &
1668 "Keyword IGNORE_EXCITED must be active for recursive diagonalization.")
1669 END IF
1670
1671 END SUBROUTINE mixed_cdft_read_block_diag
1672
1673! **************************************************************************************************
1674!> \brief Assembles the matrix blocks from the mixed CDFT Hamiltonian.
1675!> \param mixed_cdft the env that holds the CDFT states
1676!> \param blocks list of CDFT states defining the matrix blocks
1677!> \param H_block list of Hamiltonian matrix blocks
1678!> \param S_block list of overlap matrix blocks
1679!> \par History
1680!> 01.18 created [Nico Holmberg]
1681! **************************************************************************************************
1682 SUBROUTINE mixed_cdft_get_blocks(mixed_cdft, blocks, H_block, S_block)
1683 TYPE(mixed_cdft_type), POINTER :: mixed_cdft
1684 TYPE(cp_1d_i_p_type), ALLOCATABLE, DIMENSION(:) :: blocks
1685 TYPE(cp_2d_r_p_type), ALLOCATABLE, DIMENSION(:), &
1686 INTENT(OUT) :: h_block, s_block
1687
1688 INTEGER :: i, icol, irow, j, k, nblk
1689
1690 EXTERNAL :: dsygv
1691
1692 cpassert(ASSOCIATED(mixed_cdft))
1693
1694 nblk = SIZE(blocks)
1695 ALLOCATE (h_block(nblk), s_block(nblk))
1696 DO i = 1, nblk
1697 NULLIFY (h_block(i)%array)
1698 NULLIFY (s_block(i)%array)
1699 ALLOCATE (h_block(i)%array(SIZE(blocks(i)%array), SIZE(blocks(i)%array)))
1700 ALLOCATE (s_block(i)%array(SIZE(blocks(i)%array), SIZE(blocks(i)%array)))
1701 icol = 0
1702 DO j = 1, SIZE(blocks(i)%array)
1703 irow = 0
1704 icol = icol + 1
1705 DO k = 1, SIZE(blocks(i)%array)
1706 irow = irow + 1
1707 h_block(i)%array(irow, icol) = mixed_cdft%results%H(blocks(i)%array(k), blocks(i)%array(j))
1708 s_block(i)%array(irow, icol) = mixed_cdft%results%S(blocks(i)%array(k), blocks(i)%array(j))
1709 END DO
1710 END DO
1711 ! Check that none of the interaction energies is repulsive
1712 IF (any(h_block(i)%array .GE. 0.0_dp)) &
1713 CALL cp_abort(__location__, &
1714 "At least one of the interaction energies within block "//trim(adjustl(cp_to_string(i)))// &
1715 " is repulsive.")
1716 END DO
1717
1718 END SUBROUTINE mixed_cdft_get_blocks
1719
1720! **************************************************************************************************
1721!> \brief Diagonalizes each of the matrix blocks.
1722!> \param blocks list of CDFT states defining the matrix blocks
1723!> \param H_block list of Hamiltonian matrix blocks
1724!> \param S_block list of overlap matrix blocks
1725!> \param eigenvalues list of eigenvalues for each block
1726!> \par History
1727!> 01.18 created [Nico Holmberg]
1728! **************************************************************************************************
1729 SUBROUTINE mixed_cdft_diagonalize_blocks(blocks, H_block, S_block, eigenvalues)
1730 TYPE(cp_1d_i_p_type), ALLOCATABLE, DIMENSION(:) :: blocks
1731 TYPE(cp_2d_r_p_type), ALLOCATABLE, DIMENSION(:) :: h_block, s_block
1732 TYPE(cp_1d_r_p_type), ALLOCATABLE, DIMENSION(:), &
1733 INTENT(OUT) :: eigenvalues
1734
1735 INTEGER :: i, info, nblk, work_array_size
1736 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: work
1737 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :) :: h_mat_copy, s_mat_copy
1738
1739 EXTERNAL :: dsygv
1740
1741 nblk = SIZE(blocks)
1742 ALLOCATE (eigenvalues(nblk))
1743 DO i = 1, nblk
1744 NULLIFY (eigenvalues(i)%array)
1745 ALLOCATE (eigenvalues(i)%array(SIZE(blocks(i)%array)))
1746 eigenvalues(i)%array = 0.0_dp
1747 ! Workspace query
1748 ALLOCATE (work(1))
1749 info = 0
1750 ALLOCATE (h_mat_copy(SIZE(blocks(i)%array), SIZE(blocks(i)%array)))
1751 ALLOCATE (s_mat_copy(SIZE(blocks(i)%array), SIZE(blocks(i)%array)))
1752 h_mat_copy(:, :) = h_block(i)%array(:, :) ! Need explicit copies because dsygv destroys original values
1753 s_mat_copy(:, :) = s_block(i)%array(:, :)
1754 CALL dsygv(1, 'V', 'U', SIZE(blocks(i)%array), h_mat_copy, SIZE(blocks(i)%array), &
1755 s_mat_copy, SIZE(blocks(i)%array), eigenvalues(i)%array, work, -1, info)
1756 work_array_size = nint(work(1))
1757 DEALLOCATE (h_mat_copy, s_mat_copy)
1758 ! Allocate work array
1759 DEALLOCATE (work)
1760 ALLOCATE (work(work_array_size))
1761 work = 0.0_dp
1762 ! Solve Hc = eSc
1763 info = 0
1764 CALL dsygv(1, 'V', 'U', SIZE(blocks(i)%array), h_block(i)%array, SIZE(blocks(i)%array), &
1765 s_block(i)%array, SIZE(blocks(i)%array), eigenvalues(i)%array, work, work_array_size, info)
1766 IF (info /= 0) THEN
1767 IF (info > SIZE(blocks(i)%array)) THEN
1768 cpabort("Matrix S is not positive definite")
1769 ELSE
1770 cpabort("Diagonalization of H matrix failed.")
1771 END IF
1772 END IF
1773 DEALLOCATE (work)
1774 END DO
1775
1776 END SUBROUTINE mixed_cdft_diagonalize_blocks
1777
1778! **************************************************************************************************
1779!> \brief Assembles the new block diagonalized mixed CDFT Hamiltonian and overlap matrices.
1780!> \param mixed_cdft the env that holds the CDFT states
1781!> \param blocks list of CDFT states defining the matrix blocks
1782!> \param H_block list of Hamiltonian matrix blocks
1783!> \param eigenvalues list of eigenvalues for each block
1784!> \param n size of the new Hamiltonian and overlap matrices
1785!> \param iounit the output unit
1786!> \par History
1787!> 01.18 created [Nico Holmberg]
1788! **************************************************************************************************
1789 SUBROUTINE mixed_cdft_assemble_block_diag(mixed_cdft, blocks, H_block, eigenvalues, &
1790 n, iounit)
1791 TYPE(mixed_cdft_type), POINTER :: mixed_cdft
1792 TYPE(cp_1d_i_p_type), ALLOCATABLE, DIMENSION(:) :: blocks
1793 TYPE(cp_2d_r_p_type), ALLOCATABLE, DIMENSION(:) :: h_block
1794 TYPE(cp_1d_r_p_type), ALLOCATABLE, DIMENSION(:) :: eigenvalues
1795 INTEGER :: n, iounit
1796
1797 CHARACTER(LEN=20) :: ilabel, jlabel
1798 CHARACTER(LEN=3) :: tmp
1799 INTEGER :: i, icol, ipermutation, irow, j, k, l, &
1800 nblk, npermutations
1801 LOGICAL :: ignore_excited
1802 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :) :: h_mat, h_offdiag, s_mat, s_offdiag
1803
1804 EXTERNAL :: dsygv
1805
1806 ALLOCATE (h_mat(n, n), s_mat(n, n))
1807 nblk = SIZE(blocks)
1808 ignore_excited = (nblk == n)
1809 ! The diagonal contains the eigenvalues of each block
1810 IF (iounit > 0) WRITE (iounit, '(/,T3,A)') "Eigenvalues of the block diagonalized states"
1811 h_mat(:, :) = 0.0_dp
1812 s_mat(:, :) = 0.0_dp
1813 k = 1
1814 DO i = 1, nblk
1815 IF (iounit > 0) WRITE (iounit, '(T6,A,I3)') "Block", i
1816 DO j = 1, SIZE(eigenvalues(i)%array)
1817 h_mat(k, k) = eigenvalues(i)%array(j)
1818 s_mat(k, k) = 1.0_dp
1819 k = k + 1
1820 IF (iounit > 0) THEN
1821 IF (j == 1) THEN
1822 WRITE (iounit, '(T9,A,T58,(3X,F20.14))') 'Ground state energy:', eigenvalues(i)%array(j)
1823 ELSE
1824 WRITE (iounit, '(T9,A,I2,A,T58,(3X,F20.14))') &
1825 'Excited state (', j - 1, ' ) energy:', eigenvalues(i)%array(j)
1826 END IF
1827 END IF
1828 IF (ignore_excited .AND. j == 1) EXIT
1829 END DO
1830 END DO
1831 ! Transform the off-diagonal blocks using the eigenvectors of each block
1832 npermutations = nblk*(nblk - 1)/2
1833 IF (iounit > 0) WRITE (iounit, '(/,T3,A)') "Interactions between block diagonalized states"
1834 DO ipermutation = 1, npermutations
1835 CALL map_permutation_to_states(nblk, ipermutation, i, j)
1836 ! Get the untransformed off-diagonal block
1837 ALLOCATE (h_offdiag(SIZE(blocks(i)%array), SIZE(blocks(j)%array)))
1838 ALLOCATE (s_offdiag(SIZE(blocks(i)%array), SIZE(blocks(j)%array)))
1839 icol = 0
1840 DO k = 1, SIZE(blocks(j)%array)
1841 irow = 0
1842 icol = icol + 1
1843 DO l = 1, SIZE(blocks(i)%array)
1844 irow = irow + 1
1845 h_offdiag(irow, icol) = mixed_cdft%results%H(blocks(i)%array(l), blocks(j)%array(k))
1846 s_offdiag(irow, icol) = mixed_cdft%results%S(blocks(i)%array(l), blocks(j)%array(k))
1847 END DO
1848 END DO
1849 ! Check that none of the interaction energies is repulsive
1850 IF (any(h_offdiag .GE. 0.0_dp)) &
1851 CALL cp_abort(__location__, &
1852 "At least one of the interaction energies between blocks "//trim(adjustl(cp_to_string(i)))// &
1853 " and "//trim(adjustl(cp_to_string(j)))//" is repulsive.")
1854 ! Now transform: C_i^T * H * C_j
1855 h_offdiag(:, :) = matmul(h_offdiag, h_block(j)%array)
1856 h_offdiag(:, :) = matmul(transpose(h_block(i)%array), h_offdiag)
1857 s_offdiag(:, :) = matmul(s_offdiag, h_block(j)%array)
1858 s_offdiag(:, :) = matmul(transpose(h_block(i)%array), s_offdiag)
1859 ! Make sure the transformation preserves the sign of elements in the S and H matrices
1860 ! The S/H matrices contain only positive/negative values so that any sign flipping occurs in the
1861 ! same elements in both matrices
1862 ! Check for sign flipping using the S matrix
1863 IF (any(s_offdiag .LT. 0.0_dp)) THEN
1864 DO l = 1, SIZE(s_offdiag, 2)
1865 DO k = 1, SIZE(s_offdiag, 1)
1866 IF (s_offdiag(k, l) .LT. 0.0_dp) THEN
1867 s_offdiag(k, l) = -1.0_dp*s_offdiag(k, l)
1868 h_offdiag(k, l) = -1.0_dp*h_offdiag(k, l)
1869 END IF
1870 END DO
1871 END DO
1872 END IF
1873 IF (ignore_excited) THEN
1874 h_mat(i, j) = h_offdiag(1, 1)
1875 h_mat(j, i) = h_mat(i, j)
1876 s_mat(i, j) = s_offdiag(1, 1)
1877 s_mat(j, i) = s_mat(i, j)
1878 ELSE
1879 irow = 1
1880 icol = 1
1881 DO k = 1, i - 1
1882 irow = irow + SIZE(blocks(k)%array)
1883 END DO
1884 DO k = 1, j - 1
1885 icol = icol + SIZE(blocks(k)%array)
1886 END DO
1887 h_mat(irow:irow + SIZE(h_offdiag, 1) - 1, icol:icol + SIZE(h_offdiag, 2) - 1) = h_offdiag(:, :)
1888 h_mat(icol:icol + SIZE(h_offdiag, 2) - 1, irow:irow + SIZE(h_offdiag, 1) - 1) = transpose(h_offdiag)
1889 s_mat(irow:irow + SIZE(h_offdiag, 1) - 1, icol:icol + SIZE(h_offdiag, 2) - 1) = s_offdiag(:, :)
1890 s_mat(icol:icol + SIZE(h_offdiag, 2) - 1, irow:irow + SIZE(h_offdiag, 1) - 1) = transpose(s_offdiag)
1891 END IF
1892 IF (iounit > 0) THEN
1893 WRITE (iounit, '(/,T3,A)') repeat('#', 39)
1894 WRITE (iounit, '(T3,A,I3,A,I3,A)') '###### Blocks I =', i, ' and J = ', j, ' ######'
1895 WRITE (iounit, '(T3,A)') repeat('#', 39)
1896 WRITE (iounit, '(T3,A)') 'Interaction energies'
1897 DO irow = 1, SIZE(h_offdiag, 1)
1898 ilabel = "(ground state)"
1899 IF (irow > 1) THEN
1900 IF (ignore_excited) EXIT
1901 WRITE (tmp, '(I3)') irow - 1
1902 ilabel = "(excited state "//trim(adjustl(tmp))//")"
1903 END IF
1904 DO icol = 1, SIZE(h_offdiag, 2)
1905 jlabel = "(ground state)"
1906 IF (icol > 1) THEN
1907 IF (ignore_excited) EXIT
1908 WRITE (tmp, '(I3)') icol - 1
1909 jlabel = "(excited state "//trim(adjustl(tmp))//")"
1910 END IF
1911 WRITE (iounit, '(T6,A,T58,(3X,F20.14))') trim(ilabel)//'-'//trim(jlabel)//':', h_offdiag(irow, icol)
1912 END DO
1913 END DO
1914 WRITE (iounit, '(T3,A)') 'Overlaps'
1915 DO irow = 1, SIZE(h_offdiag, 1)
1916 ilabel = "(ground state)"
1917 IF (irow > 1) THEN
1918 IF (ignore_excited) EXIT
1919 ilabel = "(excited state)"
1920 WRITE (tmp, '(I3)') irow - 1
1921 ilabel = "(excited state "//trim(adjustl(tmp))//")"
1922 END IF
1923 DO icol = 1, SIZE(h_offdiag, 2)
1924 jlabel = "(ground state)"
1925 IF (icol > 1) THEN
1926 IF (ignore_excited) EXIT
1927 WRITE (tmp, '(I3)') icol - 1
1928 jlabel = "(excited state "//trim(adjustl(tmp))//")"
1929 END IF
1930 WRITE (iounit, '(T6,A,T58,(3X,F20.14))') trim(ilabel)//'-'//trim(jlabel)//':', s_offdiag(irow, icol)
1931 END DO
1932 END DO
1933 END IF
1934 DEALLOCATE (h_offdiag, s_offdiag)
1935 END DO
1936 CALL mixed_cdft_result_type_set(mixed_cdft%results, h=h_mat, s=s_mat)
1937 ! Deallocate work
1938 DEALLOCATE (h_mat, s_mat)
1939
1940 END SUBROUTINE mixed_cdft_assemble_block_diag
1941
1942END 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...
subroutine, public dbcsr_release_p(matrix)
...
subroutine, public dbcsr_desymmetrize(matrix_a, matrix_b)
...
subroutine, public dbcsr_get_info(matrix, nblkrows_total, nblkcols_total, nfullrows_total, nfullcols_total, nblkrows_local, nblkcols_local, nfullrows_local, nfullcols_local, my_prow, my_pcol, local_rows, local_cols, proc_row_dist, proc_col_dist, row_blk_size, col_blk_size, row_blk_offset, col_blk_offset, distribution, name, matrix_type, group)
...
subroutine, public dbcsr_init_p(matrix)
...
subroutine, public dbcsr_release(matrix)
...
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, ipi_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_string_length
Definition kinds.F:57
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:77
subroutine, public pw_grid_release(pw_grid)
releases the given pw grid
Definition pw_grids.F:2163
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_pp, 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, harris_env, dispersion_env, gcp_env, vee, rho_external, external_vxc, mask, mp2_env, bs_env, kg_env, wanniercentres, atprop, ls_scf_env, do_transport, transport_env, v_hartree_rspace, s_mstruct_changed, rho_changed, potential_changed, forces_up_to_date, mscfg_env, almo_scf_env, gradient_history, variable_history, embed_pot, spin_embed_pot, polar_env, mos_last_converged, eeq, rhs, do_rixs, tb_tblite)
Get the QUICKSTEP environment.
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, silent)
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.