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