116#include "./base/base_uses.f90"
122 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'mixed_cdft_methods'
123 LOGICAL,
PARAMETER,
PRIVATE :: debug_this_module = .false.
140 LOGICAL,
INTENT(IN) :: calculate_forces
142 CHARACTER(len=*),
PARAMETER :: routinen =
'mixed_cdft_init'
144 INTEGER :: et_freq, handle, iforce_eval, iounit, &
145 mixing_type, nforce_eval
146 LOGICAL :: explicit, is_parallel, is_qmmm
155 md_section, mixed_section, &
156 print_section, root_section
158 NULLIFY (subsys_mix, force_env_qs, force_env_section, print_section, &
159 root_section, mixed_section, md_section, mixed_env, mixed_cdft, &
162 NULLIFY (settings%grid_span, settings%npts, settings%cutoff, settings%rel_cutoff, &
163 settings%spherical, settings%rs_dims, settings%odd, settings%atoms, &
164 settings%coeffs, settings%si, settings%sr, &
165 settings%cutoffs, settings%radii)
169 cpassert(
ASSOCIATED(force_env))
170 nforce_eval =
SIZE(force_env%sub_force_env)
171 CALL timeset(routinen, handle)
172 CALL force_env_get(force_env=force_env, force_env_section=force_env_section)
173 mixed_env => force_env%mixed_env
179 IF (mixing_type ==
mix_cdft .AND. .NOT.
ASSOCIATED(mixed_env%cdft_control))
THEN
180 mixed_env%do_mixed_cdft = .true.
181 IF (mixed_env%do_mixed_cdft)
THEN
183 IF (nforce_eval .LT. 2) &
184 CALL cp_abort(__location__, &
185 "Mixed CDFT calculation requires at least 2 force_evals.")
190 cpabort(
"Please disable section &MAPPING for mixed CDFT calculations")
192 IF (et_freq .LT. 0)
THEN
193 mixed_env%do_mixed_et = .false.
195 mixed_env%do_mixed_et = .true.
196 IF (et_freq == 0)
THEN
197 mixed_env%et_freq = 1
199 mixed_env%et_freq = et_freq
204 DO iforce_eval = 1, nforce_eval
205 IF (.NOT.
ASSOCIATED(force_env%sub_force_env(iforce_eval)%force_env)) cycle
206 SELECT CASE (force_env%sub_force_env(iforce_eval)%force_env%in_use)
208 force_env_qs => force_env%sub_force_env(iforce_eval)%force_env
212 force_env_qs => force_env%sub_force_env(iforce_eval)%force_env
214 cpabort(
"No force mixing allowed for mixed CDFT QM/MM")
218 cpassert(
ASSOCIATED(force_env_qs))
221 IF (.NOT. is_qmmm)
THEN
225 particles=particles_mix)
227 CALL get_qs_env(force_env_qs%qmmm_env%qs_env, &
228 cp_subsys=subsys_mix)
230 particles=particles_mix)
233 ALLOCATE (mixed_cdft)
235 mixed_cdft%first_iteration = .true.
237 IF (mixed_env%ngroups == 1)
THEN
240 ELSE IF (mixed_env%ngroups == 2)
THEN
242 IF (is_parallel)
THEN
245 IF (.NOT. nforce_eval == 2) &
246 CALL cp_abort(__location__, &
247 "Parallel mode mixed CDFT calculation supports only 2 force_evals.")
256 mixed_env%do_mixed_qmmm_cdft = is_qmmm
259 mixed_cdft%dlb = mixed_cdft%dlb .AND. calculate_forces
261 IF (mixed_cdft%dlb)
THEN
262 ALLOCATE (mixed_cdft%dlb_control)
263 NULLIFY (mixed_cdft%dlb_control%weight, mixed_cdft%dlb_control%gradients, &
264 mixed_cdft%dlb_control%cavity, mixed_cdft%dlb_control%target_list, &
265 mixed_cdft%dlb_control%bo, mixed_cdft%dlb_control%expected_work, &
266 mixed_cdft%dlb_control%prediction_error, mixed_cdft%dlb_control%sendbuff, &
267 mixed_cdft%dlb_control%recvbuff, mixed_cdft%dlb_control%recv_work_repl, &
268 mixed_cdft%dlb_control%recv_info)
270 r_val=mixed_cdft%dlb_control%load_scale)
272 r_val=mixed_cdft%dlb_control%very_overloaded)
274 i_val=mixed_cdft%dlb_control%more_work)
277 mixed_cdft%calculate_metric = .false.
278 mixed_cdft%wfn_overlap_method = .false.
279 mixed_cdft%use_lowdin = .false.
280 mixed_cdft%do_ci = .false.
281 mixed_cdft%nonortho_coupling = .false.
282 mixed_cdft%identical_constraints = .true.
283 mixed_cdft%block_diagonalize = .false.
284 IF (mixed_env%do_mixed_et)
THEN
286 l_val=mixed_cdft%calculate_metric)
288 l_val=mixed_cdft%wfn_overlap_method)
290 l_val=mixed_cdft%use_lowdin)
292 l_val=mixed_cdft%do_ci)
294 l_val=mixed_cdft%nonortho_coupling)
296 l_val=mixed_cdft%block_diagonalize)
300 IF (mixed_cdft%eps_svd .LT. 0.0_dp .OR. mixed_cdft%eps_svd .GT. 1.0_dp) &
301 cpabort(
"Illegal value for EPS_SVD. Value must be between 0.0 and 1.0.")
307 mixed_cdft%sim_step = mixed_cdft%sim_step - 1
311 settings, natom=
SIZE(particles_mix%els))
319 WRITE (iounit, fmt=
"(T2,A,T71)") &
320 "MIXED_CDFT| Activating mixed CDFT calculation"
321 WRITE (iounit, fmt=
"(T2,A,T71,I10)") &
322 "MIXED_CDFT| Number of CDFT states: ", nforce_eval
323 SELECT CASE (mixed_cdft%run_type)
325 WRITE (iounit, fmt=
"(T2,A,T71)") &
326 "MIXED_CDFT| CDFT states calculation mode: parallel with build"
327 WRITE (iounit, fmt=
"(T2,A,T71)") &
328 "MIXED_CDFT| Becke constraint is first built using all available processors"
329 WRITE (iounit, fmt=
"(T2,A,T71)") &
330 " and then copied to both states with their own processor groups"
332 WRITE (iounit, fmt=
"(T2,A,T71)") &
333 "MIXED_CDFT| CDFT states calculation mode: serial"
334 IF (mixed_cdft%identical_constraints)
THEN
335 WRITE (iounit, fmt=
"(T2,A,T71)") &
336 "MIXED_CDFT| The constraints are built before the SCF procedure of the first"
337 WRITE (iounit, fmt=
"(T2,A,T71)") &
338 " CDFT state and subsequently copied to the other states"
340 WRITE (iounit, fmt=
"(T2,A,T71)") &
341 "MIXED_CDFT| The constraints are separately built for all CDFT states"
344 WRITE (iounit, fmt=
"(T2,A,T71)") &
345 "MIXED_CDFT| CDFT states calculation mode: parallel without build"
346 WRITE (iounit, fmt=
"(T2,A,T71)") &
347 "MIXED_CDFT| The constraints are separately built for all CDFT states"
349 cpabort(
"Unknown mixed CDFT run type.")
351 WRITE (iounit, fmt=
"(T2,A,T71,L10)") &
352 "MIXED_CDFT| Calculating electronic coupling between states: ", mixed_env%do_mixed_et
353 WRITE (iounit, fmt=
"(T2,A,T71,L10)") &
354 "MIXED_CDFT| Calculating electronic coupling reliability metric: ", mixed_cdft%calculate_metric
355 WRITE (iounit, fmt=
"(T2,A,T71,L10)") &
356 "MIXED_CDFT| Configuration interaction (CDFT-CI) was requested: ", mixed_cdft%do_ci
357 WRITE (iounit, fmt=
"(T2,A,T71,L10)") &
358 "MIXED_CDFT| Block diagonalizing the mixed CDFT Hamiltonian: ", mixed_cdft%block_diagonalize
360 WRITE (iounit, fmt=
"(T2,A,T71,L10)") &
361 "MIXED_CDFT| Dynamic load balancing enabled: ", mixed_cdft%dlb
362 IF (mixed_cdft%dlb)
THEN
363 WRITE (iounit, fmt=
"(T2,A,T71)")
"MIXED_CDFT| Dynamic load balancing parameters:"
364 WRITE (iounit, fmt=
"(T2,A,T71,F10.2)") &
365 "MIXED_CDFT| load_scale:", mixed_cdft%dlb_control%load_scale
366 WRITE (iounit, fmt=
"(T2,A,T71,F10.2)") &
367 "MIXED_CDFT| very_overloaded:", mixed_cdft%dlb_control%very_overloaded
368 WRITE (iounit, fmt=
"(T2,A,T71,I10)") &
369 "MIXED_CDFT| more_work:", mixed_cdft%dlb_control%more_work
372 IF (mixed_env%do_mixed_et)
THEN
373 IF (mixed_cdft%eps_svd == 0.0_dp)
THEN
374 WRITE (iounit, fmt=
"(T2,A,T71)")
"MIXED_CDFT| Matrix inversions calculated with LU decomposition."
376 WRITE (iounit, fmt=
"(T2,A,T71)")
"MIXED_CDFT| Matrix inversions calculated with SVD decomposition."
377 WRITE (iounit, fmt=
"(T2,A,T71,ES10.2)")
"MIXED_CDFT| EPS_SVD:", mixed_cdft%eps_svd
385 "MIXED%MIXED_CDFT%PRINT%PROGRAM_RUN_INFO")
386 CALL timestop(handle)
400 LOGICAL,
INTENT(IN) :: calculate_forces
401 INTEGER,
INTENT(IN),
OPTIONAL :: iforce_eval
406 cpassert(
ASSOCIATED(force_env))
407 CALL get_mixed_env(force_env%mixed_env, cdft_control=mixed_cdft)
408 cpassert(
ASSOCIATED(mixed_cdft))
409 IF (.NOT.
PRESENT(iforce_eval))
THEN
410 SELECT CASE (mixed_cdft%run_type)
412 CALL mixed_cdft_build_weight_parallel(force_env, calculate_forces)
414 CALL mixed_cdft_set_flags(force_env)
419 SELECT CASE (mixed_cdft%run_type)
421 CALL mixed_cdft_transfer_weight(force_env, calculate_forces, iforce_eval)
436 SUBROUTINE mixed_cdft_build_weight_parallel(force_env, calculate_forces)
438 LOGICAL,
INTENT(IN) :: calculate_forces
440 CHARACTER(len=*),
PARAMETER :: routinen =
'mixed_cdft_build_weight_parallel'
442 INTEGER :: handle, handle2, i, iforce_eval, ind, index(6), iounit, j, lb_min, &
443 my_special_work, natom, nforce_eval, recv_offset, ub_max
444 INTEGER,
DIMENSION(2, 3) :: bo
445 INTEGER,
DIMENSION(:),
POINTER :: lb, sendbuffer_i, ub
446 REAL(kind=
dp) :: t1, t2
457 TYPE(
pw_pool_type),
POINTER :: auxbas_pw_pool, mixed_auxbas_pw_pool
463 INTEGER,
DIMENSION(:), &
464 POINTER :: iv => null()
465 REAL(kind=
dp),
POINTER, &
466 DIMENSION(:, :, :) :: r3 => null()
467 REAL(kind=
dp),
POINTER, &
468 DIMENSION(:, :, :, :) :: r4 => null()
470 TYPE(buffers),
DIMENSION(:),
POINTER :: recvbuffer
472 NULLIFY (subsys_mix, force_env_qs, particles_mix, force_env_section, print_section, &
473 mixed_env, mixed_cdft, pw_env, auxbas_pw_pool, mixed_auxbas_pw_pool, &
474 qs_env, dft_control, sendbuffer_i, lb, ub, req_total, recvbuffer, &
475 cdft_control, cdft_control_target)
478 cpassert(
ASSOCIATED(force_env))
479 nforce_eval =
SIZE(force_env%sub_force_env)
480 CALL timeset(routinen, handle)
485 force_env_section=force_env_section)
487 particles=particles_mix)
488 DO iforce_eval = 1, nforce_eval
489 IF (.NOT.
ASSOCIATED(force_env%sub_force_env(iforce_eval)%force_env)) cycle
490 SELECT CASE (force_env%sub_force_env(iforce_eval)%force_env%in_use)
492 force_env_qs => force_env%sub_force_env(iforce_eval)%force_env
494 force_env_qs => force_env%sub_force_env(iforce_eval)%force_env
499 IF (.NOT. force_env%mixed_env%do_mixed_qmmm_cdft)
THEN
504 particles=particles_mix)
506 qs_env => force_env_qs%qmmm_env%qs_env
509 particles=particles_mix)
511 mixed_env => force_env%mixed_env
515 cpassert(
ASSOCIATED(mixed_cdft))
516 cdft_control => mixed_cdft%cdft_control
517 cpassert(
ASSOCIATED(cdft_control))
519 CALL pw_env_get(pw_env=mixed_cdft%pw_env, auxbas_pw_pool=mixed_auxbas_pw_pool)
520 natom =
SIZE(particles_mix%els)
521 CALL mixed_becke_constraint(force_env, calculate_forces)
523 mixed_cdft%sim_step = mixed_cdft%sim_step + 1
524 CALL get_qs_env(qs_env, pw_env=pw_env, dft_control=dft_control)
525 cdft_control_target => dft_control%qs_control%cdft_control
526 cpassert(dft_control%qs_control%cdft)
527 cpassert(
ASSOCIATED(cdft_control_target))
528 CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool)
529 bo = auxbas_pw_pool%pw_grid%bounds_local
531 IF (mixed_cdft%is_special)
THEN
536 ALLOCATE (recvbuffer(
SIZE(mixed_cdft%source_list)))
537 ALLOCATE (req_total(my_special_work*
SIZE(mixed_cdft%dest_list) +
SIZE(mixed_cdft%source_list)))
538 ALLOCATE (lb(
SIZE(mixed_cdft%source_list)), ub(
SIZE(mixed_cdft%source_list)))
539 IF (cdft_control%becke_control%cavity_confine)
THEN
541 ALLOCATE (sendbuffer_i(2))
542 sendbuffer_i = cdft_control%becke_control%confine_bounds
543 DO i = 1,
SIZE(mixed_cdft%source_list)
544 ALLOCATE (recvbuffer(i)%iv(2))
545 CALL force_env%para_env%irecv(msgout=recvbuffer(i)%iv, source=mixed_cdft%source_list(i), &
546 request=req_total(i))
548 DO i = 1, my_special_work
549 DO j = 1,
SIZE(mixed_cdft%dest_list)
550 ind = j + (i - 1)*
SIZE(mixed_cdft%dest_list) +
SIZE(mixed_cdft%source_list)
551 CALL force_env%para_env%isend(msgin=sendbuffer_i, &
552 dest=mixed_cdft%dest_list(j) + (i - 1)*force_env%para_env%num_pe/2, &
553 request=req_total(ind))
558 DEALLOCATE (sendbuffer_i)
561 DO i = 1,
SIZE(mixed_cdft%source_list)
562 lb(i) = recvbuffer(i)%iv(1)
563 ub(i) = recvbuffer(i)%iv(2)
564 IF (lb(i) .LT. lb_min) lb_min = lb(i)
565 IF (ub(i) .GT. ub_max) ub_max = ub(i)
566 DEALLOCATE (recvbuffer(i)%iv)
569 IF (mixed_cdft%dlb)
THEN
570 IF (any(mixed_cdft%dlb_control%recv_work_repl))
THEN
571 DO j = 1,
SIZE(mixed_cdft%dlb_control%recv_work_repl)
572 IF (mixed_cdft%dlb_control%recv_work_repl(j))
THEN
573 DO i = 1,
SIZE(mixed_cdft%dlb_control%recvbuff(j)%buffs)
574 IF (lbound(mixed_cdft%dlb_control%recvbuff(j)%buffs(i)%weight, 3) &
575 .LT. lb_min) lb_min = lbound(mixed_cdft%dlb_control%recvbuff(j)%buffs(i)%weight, 3)
576 IF (ubound(mixed_cdft%dlb_control%recvbuff(j)%buffs(i)%weight, 3) &
577 .GT. ub_max) ub_max = ubound(mixed_cdft%dlb_control%recvbuff(j)%buffs(i)%weight, 3)
591 CALL timeset(routinen//
"_comm", handle2)
592 DO j = 1,
SIZE(recvbuffer)
594 IF (mixed_cdft%is_special)
THEN
595 recvbuffer(j)%imap = (/mixed_cdft%source_list_bo(1, j), mixed_cdft%source_list_bo(2, j), &
596 mixed_cdft%source_list_bo(3, j), mixed_cdft%source_list_bo(4, j), &
598 ELSE IF (mixed_cdft%is_pencil)
THEN
599 recvbuffer(j)%imap = (/bo(1, 1), bo(2, 1), mixed_cdft%recv_bo(ind), mixed_cdft%recv_bo(ind + 1), lb(j), ub(j)/)
601 recvbuffer(j)%imap = (/mixed_cdft%recv_bo(ind), mixed_cdft%recv_bo(ind + 1), bo(1, 2), bo(2, 2), lb(j), ub(j)/)
604 IF (mixed_cdft%dlb .AND. .NOT. mixed_cdft%is_special)
THEN
605 IF (mixed_cdft%dlb_control%recv_work_repl(1) .OR. mixed_cdft%dlb_control%recv_work_repl(2))
THEN
608 IF (mixed_cdft%dlb_control%recv_work_repl(j)) &
609 recv_offset = sum(mixed_cdft%dlb_control%recv_info(j)%target_list(2, :))
610 IF (mixed_cdft%is_pencil)
THEN
611 recvbuffer(j)%imap(1) = recvbuffer(j)%imap(1) + recv_offset
613 recvbuffer(j)%imap(3) = recvbuffer(j)%imap(3) + recv_offset
620 DO j = 1,
SIZE(mixed_cdft%source_list)
621 ALLOCATE (recvbuffer(j)%r3(recvbuffer(j)%imap(1):recvbuffer(j)%imap(2), &
622 recvbuffer(j)%imap(3):recvbuffer(j)%imap(4), &
623 recvbuffer(j)%imap(5):recvbuffer(j)%imap(6)))
625 CALL force_env%para_env%irecv(msgout=recvbuffer(j)%r3, source=mixed_cdft%source_list(j), &
626 request=req_total(j))
628 DO i = 1, my_special_work
629 DO j = 1,
SIZE(mixed_cdft%dest_list)
630 ind = j + (i - 1)*
SIZE(mixed_cdft%dest_list) +
SIZE(mixed_cdft%source_list)
631 IF (mixed_cdft%is_special)
THEN
632 CALL force_env%para_env%isend(msgin=mixed_cdft%sendbuff(j)%weight, &
633 dest=mixed_cdft%dest_list(j) + (i - 1)*force_env%para_env%num_pe/2, &
634 request=req_total(ind))
636 CALL force_env%para_env%isend(msgin=mixed_cdft%weight, dest=mixed_cdft%dest_list(j), &
637 request=req_total(ind))
642 IF (mixed_cdft%is_special)
THEN
643 DO j = 1,
SIZE(mixed_cdft%dest_list)
644 DEALLOCATE (mixed_cdft%sendbuff(j)%weight)
647 DEALLOCATE (mixed_cdft%weight)
651 ALLOCATE (cdft_control_target%group(1)%weight)
652 CALL auxbas_pw_pool%create_pw(cdft_control_target%group(1)%weight)
653 CALL pw_zero(cdft_control_target%group(1)%weight)
655 DO j = 1,
SIZE(mixed_cdft%source_list)
656 cdft_control_target%group(1)%weight%array(recvbuffer(j)%imap(1):recvbuffer(j)%imap(2), &
657 recvbuffer(j)%imap(3):recvbuffer(j)%imap(4), &
658 recvbuffer(j)%imap(5):recvbuffer(j)%imap(6)) = recvbuffer(j)%r3
661 IF (mixed_cdft%dlb)
THEN
662 IF (any(mixed_cdft%dlb_control%recv_work_repl))
THEN
663 DO j = 1,
SIZE(mixed_cdft%dlb_control%recv_work_repl)
664 IF (mixed_cdft%dlb_control%recv_work_repl(j))
THEN
665 DO i = 1,
SIZE(mixed_cdft%dlb_control%recvbuff(j)%buffs)
666 index = (/lbound(mixed_cdft%dlb_control%recvbuff(j)%buffs(i)%weight, 1), &
667 ubound(mixed_cdft%dlb_control%recvbuff(j)%buffs(i)%weight, 1), &
668 lbound(mixed_cdft%dlb_control%recvbuff(j)%buffs(i)%weight, 2), &
669 ubound(mixed_cdft%dlb_control%recvbuff(j)%buffs(i)%weight, 2), &
670 lbound(mixed_cdft%dlb_control%recvbuff(j)%buffs(i)%weight, 3), &
671 ubound(mixed_cdft%dlb_control%recvbuff(j)%buffs(i)%weight, 3)/)
672 cdft_control_target%group(1)%weight%array(index(1):index(2), &
674 index(5):index(6)) = &
675 mixed_cdft%dlb_control%recvbuff(j)%buffs(i)%weight
676 DEALLOCATE (mixed_cdft%dlb_control%recvbuff(j)%buffs(i)%weight)
683 IF (cdft_control%becke_control%cavity_confine)
THEN
684 DO j = 1,
SIZE(mixed_cdft%source_list)
685 CALL force_env%para_env%irecv(msgout=recvbuffer(j)%r3, source=mixed_cdft%source_list(j), &
686 request=req_total(j))
688 DO i = 1, my_special_work
689 DO j = 1,
SIZE(mixed_cdft%dest_list)
690 ind = j + (i - 1)*
SIZE(mixed_cdft%dest_list) +
SIZE(mixed_cdft%source_list)
691 IF (mixed_cdft%is_special)
THEN
692 CALL force_env%para_env%isend(msgin=mixed_cdft%sendbuff(j)%cavity, &
693 dest=mixed_cdft%dest_list(j) + (i - 1)*force_env%para_env%num_pe/2, &
694 request=req_total(ind))
696 CALL force_env%para_env%isend(msgin=mixed_cdft%cavity, dest=mixed_cdft%dest_list(j), &
697 request=req_total(ind))
702 IF (mixed_cdft%is_special)
THEN
703 DO j = 1,
SIZE(mixed_cdft%dest_list)
704 DEALLOCATE (mixed_cdft%sendbuff(j)%cavity)
707 DEALLOCATE (mixed_cdft%cavity)
710 ALLOCATE (cdft_control_target%becke_control%cavity_mat(bo(1, 1):bo(2, 1), &
713 cdft_control_target%becke_control%cavity_mat = 0.0_dp
715 DO j = 1,
SIZE(mixed_cdft%source_list)
716 cdft_control_target%becke_control%cavity_mat(recvbuffer(j)%imap(1):recvbuffer(j)%imap(2), &
717 recvbuffer(j)%imap(3):recvbuffer(j)%imap(4), &
718 recvbuffer(j)%imap(5):recvbuffer(j)%imap(6)) = recvbuffer(j)%r3
720 IF (mixed_cdft%dlb)
THEN
721 IF (any(mixed_cdft%dlb_control%recv_work_repl))
THEN
722 DO j = 1,
SIZE(mixed_cdft%dlb_control%recv_work_repl)
723 IF (mixed_cdft%dlb_control%recv_work_repl(j))
THEN
724 DO i = 1,
SIZE(mixed_cdft%dlb_control%recvbuff(j)%buffs)
725 index = (/lbound(mixed_cdft%dlb_control%recvbuff(j)%buffs(i)%cavity, 1), &
726 ubound(mixed_cdft%dlb_control%recvbuff(j)%buffs(i)%cavity, 1), &
727 lbound(mixed_cdft%dlb_control%recvbuff(j)%buffs(i)%cavity, 2), &
728 ubound(mixed_cdft%dlb_control%recvbuff(j)%buffs(i)%cavity, 2), &
729 lbound(mixed_cdft%dlb_control%recvbuff(j)%buffs(i)%cavity, 3), &
730 ubound(mixed_cdft%dlb_control%recvbuff(j)%buffs(i)%cavity, 3)/)
731 cdft_control_target%becke_control%cavity_mat(index(1):index(2), &
733 index(5):index(6)) = &
734 mixed_cdft%dlb_control%recvbuff(j)%buffs(i)%cavity
735 DEALLOCATE (mixed_cdft%dlb_control%recvbuff(j)%buffs(i)%cavity)
742 DO j = 1,
SIZE(mixed_cdft%source_list)
743 DEALLOCATE (recvbuffer(j)%r3)
745 IF (calculate_forces)
THEN
747 DO j = 1,
SIZE(mixed_cdft%source_list)
748 ALLOCATE (recvbuffer(j)%r4(3*natom, recvbuffer(j)%imap(1):recvbuffer(j)%imap(2), &
749 recvbuffer(j)%imap(3):recvbuffer(j)%imap(4), &
750 recvbuffer(j)%imap(5):recvbuffer(j)%imap(6)))
751 CALL force_env%para_env%irecv(msgout=recvbuffer(j)%r4, source=mixed_cdft%source_list(j), &
752 request=req_total(j))
754 DO i = 1, my_special_work
755 DO j = 1,
SIZE(mixed_cdft%dest_list)
756 ind = j + (i - 1)*
SIZE(mixed_cdft%dest_list) +
SIZE(mixed_cdft%source_list)
757 IF (mixed_cdft%is_special)
THEN
758 CALL force_env%para_env%isend(msgin=mixed_cdft%sendbuff(j)%gradients, &
759 dest=mixed_cdft%dest_list(j) + (i - 1)*force_env%para_env%num_pe/2, &
760 request=req_total(ind))
762 CALL force_env%para_env%isend(msgin=cdft_control%group(1)%gradients, dest=mixed_cdft%dest_list(j), &
763 request=req_total(ind))
768 IF (mixed_cdft%is_special)
THEN
769 DO j = 1,
SIZE(mixed_cdft%dest_list)
770 DEALLOCATE (mixed_cdft%sendbuff(j)%gradients)
772 DEALLOCATE (mixed_cdft%sendbuff)
774 DEALLOCATE (cdft_control%group(1)%gradients)
776 ALLOCATE (cdft_control_target%group(1)%gradients(3*natom, bo(1, 1):bo(2, 1), &
777 bo(1, 2):bo(2, 2), lb_min:ub_max))
778 DO j = 1,
SIZE(mixed_cdft%source_list)
779 cdft_control_target%group(1)%gradients(:, recvbuffer(j)%imap(1):recvbuffer(j)%imap(2), &
780 recvbuffer(j)%imap(3):recvbuffer(j)%imap(4), &
781 recvbuffer(j)%imap(5):recvbuffer(j)%imap(6)) = recvbuffer(j)%r4
782 DEALLOCATE (recvbuffer(j)%r4)
784 IF (mixed_cdft%dlb)
THEN
785 IF (any(mixed_cdft%dlb_control%recv_work_repl))
THEN
786 DO j = 1,
SIZE(mixed_cdft%dlb_control%recv_work_repl)
787 IF (mixed_cdft%dlb_control%recv_work_repl(j))
THEN
788 DO i = 1,
SIZE(mixed_cdft%dlb_control%recvbuff(j)%buffs)
789 index = (/lbound(mixed_cdft%dlb_control%recvbuff(j)%buffs(i)%gradients, 2), &
790 ubound(mixed_cdft%dlb_control%recvbuff(j)%buffs(i)%gradients, 2), &
791 lbound(mixed_cdft%dlb_control%recvbuff(j)%buffs(i)%gradients, 3), &
792 ubound(mixed_cdft%dlb_control%recvbuff(j)%buffs(i)%gradients, 3), &
793 lbound(mixed_cdft%dlb_control%recvbuff(j)%buffs(i)%gradients, 4), &
794 ubound(mixed_cdft%dlb_control%recvbuff(j)%buffs(i)%gradients, 4)/)
795 cdft_control_target%group(1)%gradients(:, index(1):index(2), &
797 index(5):index(6)) = &
798 mixed_cdft%dlb_control%recvbuff(j)%buffs(i)%gradients
799 DEALLOCATE (mixed_cdft%dlb_control%recvbuff(j)%buffs(i)%gradients)
807 IF (mixed_cdft%dlb)
THEN
808 IF (any(mixed_cdft%dlb_control%recv_work_repl))
THEN
809 DO j = 1,
SIZE(mixed_cdft%dlb_control%recv_work_repl)
810 IF (mixed_cdft%dlb_control%recv_work_repl(j))
THEN
811 IF (
ASSOCIATED(mixed_cdft%dlb_control%recv_info(j)%target_list)) &
812 DEALLOCATE (mixed_cdft%dlb_control%recv_info(j)%target_list)
813 DEALLOCATE (mixed_cdft%dlb_control%recvbuff(j)%buffs)
816 DEALLOCATE (mixed_cdft%dlb_control%recv_info, mixed_cdft%dlb_control%recvbuff)
818 IF (
ASSOCIATED(mixed_cdft%dlb_control%target_list)) &
819 DEALLOCATE (mixed_cdft%dlb_control%target_list)
820 DEALLOCATE (mixed_cdft%dlb_control%recv_work_repl)
822 DEALLOCATE (recvbuffer)
823 DEALLOCATE (req_total)
826 CALL timestop(handle2)
828 cdft_control_target%external_control = .true.
829 cdft_control_target%need_pot = .false.
830 cdft_control_target%transfer_pot = .false.
832 IF (calculate_forces)
THEN
833 cdft_control_target%becke_control%confine_bounds(2) = ub_max
834 cdft_control_target%becke_control%confine_bounds(1) = lb_min
836 CALL pw_scale(cdft_control_target%group(1)%weight, &
837 cdft_control_target%group(1)%weight%pw_grid%dvol)
839 IF (mixed_env%do_mixed_et)
THEN
840 IF (
modulo(mixed_cdft%sim_step, mixed_env%et_freq) == 0)
THEN
841 dft_control%qs_control%cdft_control%do_et = .true.
842 dft_control%qs_control%cdft_control%calculate_metric = mixed_cdft%calculate_metric
844 dft_control%qs_control%cdft_control%do_et = .false.
845 dft_control%qs_control%cdft_control%calculate_metric = .false.
850 WRITE (iounit,
'(A)')
' '
851 WRITE (iounit,
'(T2,A,F6.1,A)')
'MIXED_CDFT| Becke constraint built in ', t2 - t1,
' seconds'
852 WRITE (iounit,
'(A)')
' '
855 "MIXED%MIXED_CDFT%PRINT%PROGRAM_RUN_INFO")
856 CALL timestop(handle)
858 END SUBROUTINE mixed_cdft_build_weight_parallel
868 SUBROUTINE mixed_cdft_transfer_weight(force_env, calculate_forces, iforce_eval)
870 LOGICAL,
INTENT(IN) :: calculate_forces
871 INTEGER,
INTENT(IN) :: iforce_eval
873 CHARACTER(len=*),
PARAMETER :: routinen =
'mixed_cdft_transfer_weight'
875 INTEGER :: bounds_of(8), handle, iatom, igroup, &
876 jforce_eval, nforce_eval
877 LOGICAL,
SAVE :: first_call = .true.
880 TYPE(
force_env_type),
POINTER :: force_env_qs_source, force_env_qs_target
883 TYPE(
pw_env_type),
POINTER :: pw_env_source, pw_env_target
885 auxbas_pw_pool_target
888 NULLIFY (mixed_cdft, dft_control_source, dft_control_target, force_env_qs_source, &
889 force_env_qs_target, pw_env_source, pw_env_target, auxbas_pw_pool_source, &
890 auxbas_pw_pool_target, qs_env_source, qs_env_target, mixed_env, &
891 cdft_control_source, cdft_control_target)
892 mixed_env => force_env%mixed_env
894 CALL timeset(routinen, handle)
895 IF (iforce_eval == 1)
THEN
898 jforce_eval = iforce_eval - 1
900 nforce_eval =
SIZE(force_env%sub_force_env)
901 SELECT CASE (force_env%sub_force_env(jforce_eval)%force_env%in_use)
903 force_env_qs_source => force_env%sub_force_env(jforce_eval)%force_env
904 force_env_qs_target => force_env%sub_force_env(iforce_eval)%force_env
908 IF (.NOT. force_env%mixed_env%do_mixed_qmmm_cdft)
THEN
910 qs_env=qs_env_source)
912 qs_env=qs_env_target)
914 qs_env_source => force_env_qs_source%qmmm_env%qs_env
915 qs_env_target => force_env_qs_target%qmmm_env%qs_env
917 IF (iforce_eval == 1)
THEN
920 CALL get_qs_env(qs_env_source, dft_control=dft_control_source)
921 cdft_control_source => dft_control_source%qs_control%cdft_control
922 cdft_control_source%external_control = .false.
923 cdft_control_source%need_pot = .true.
924 IF (mixed_cdft%identical_constraints)
THEN
925 cdft_control_source%transfer_pot = .true.
927 cdft_control_source%transfer_pot = .false.
929 mixed_cdft%sim_step = mixed_cdft%sim_step + 1
932 CALL get_qs_env(qs_env_source, dft_control=dft_control_source, &
933 pw_env=pw_env_source)
934 CALL pw_env_get(pw_env_source, auxbas_pw_pool=auxbas_pw_pool_source)
935 cdft_control_source => dft_control_source%qs_control%cdft_control
936 CALL get_qs_env(qs_env_target, dft_control=dft_control_target, &
937 pw_env=pw_env_target)
938 CALL pw_env_get(pw_env_target, auxbas_pw_pool=auxbas_pw_pool_target)
939 cdft_control_target => dft_control_target%qs_control%cdft_control
941 IF (mixed_cdft%identical_constraints)
THEN
943 DO igroup = 1,
SIZE(cdft_control_target%group)
944 ALLOCATE (cdft_control_target%group(igroup)%weight)
945 CALL auxbas_pw_pool_target%create_pw(cdft_control_target%group(igroup)%weight)
947 CALL pw_copy(cdft_control_source%group(igroup)%weight, cdft_control_target%group(igroup)%weight)
948 CALL auxbas_pw_pool_source%give_back_pw(cdft_control_source%group(igroup)%weight)
949 DEALLOCATE (cdft_control_source%group(igroup)%weight)
953 IF (cdft_control_source%becke_control%cavity_confine)
THEN
954 CALL auxbas_pw_pool_target%create_pw(cdft_control_target%becke_control%cavity)
955 CALL pw_copy(cdft_control_source%becke_control%cavity, cdft_control_target%becke_control%cavity)
956 CALL auxbas_pw_pool_source%give_back_pw(cdft_control_source%becke_control%cavity)
960 IF (calculate_forces)
THEN
961 DO igroup = 1,
SIZE(cdft_control_source%group)
962 bounds_of = (/lbound(cdft_control_source%group(igroup)%gradients, 1), &
963 ubound(cdft_control_source%group(igroup)%gradients, 1), &
964 lbound(cdft_control_source%group(igroup)%gradients, 2), &
965 ubound(cdft_control_source%group(igroup)%gradients, 2), &
966 lbound(cdft_control_source%group(igroup)%gradients, 3), &
967 ubound(cdft_control_source%group(igroup)%gradients, 3), &
968 lbound(cdft_control_source%group(igroup)%gradients, 4), &
969 ubound(cdft_control_source%group(igroup)%gradients, 4)/)
970 ALLOCATE (cdft_control_target%group(igroup)% &
971 gradients(bounds_of(1):bounds_of(2), bounds_of(3):bounds_of(4), &
972 bounds_of(5):bounds_of(6), bounds_of(7):bounds_of(8)))
973 cdft_control_target%group(igroup)%gradients = cdft_control_source%group(igroup)%gradients
974 DEALLOCATE (cdft_control_source%group(igroup)%gradients)
978 IF (cdft_control_source%atomic_charges)
THEN
979 IF (.NOT.
ASSOCIATED(cdft_control_target%charge)) &
980 ALLOCATE (cdft_control_target%charge(cdft_control_target%natoms))
981 DO iatom = 1, cdft_control_target%natoms
982 CALL auxbas_pw_pool_target%create_pw(cdft_control_target%charge(iatom))
983 CALL pw_copy(cdft_control_source%charge(iatom), cdft_control_target%charge(iatom))
984 CALL auxbas_pw_pool_source%give_back_pw(cdft_control_source%charge(iatom))
988 cdft_control_target%external_control = .false.
989 cdft_control_target%need_pot = .false.
991 IF (iforce_eval == nforce_eval)
THEN
992 cdft_control_target%transfer_pot = .false.
994 cdft_control_target%transfer_pot = .true.
996 cdft_control_target%first_iteration = .false.
999 cdft_control_target%external_control = .false.
1000 cdft_control_target%need_pot = .true.
1001 cdft_control_target%transfer_pot = .false.
1002 IF (first_call)
THEN
1003 cdft_control_target%first_iteration = .true.
1005 cdft_control_target%first_iteration = .false.
1010 IF (mixed_env%do_mixed_et)
THEN
1011 IF (
modulo(mixed_cdft%sim_step, mixed_env%et_freq) == 0)
THEN
1012 IF (iforce_eval == 1)
THEN
1013 cdft_control_source%do_et = .true.
1014 cdft_control_source%calculate_metric = mixed_cdft%calculate_metric
1016 cdft_control_target%do_et = .true.
1017 cdft_control_target%calculate_metric = mixed_cdft%calculate_metric
1020 IF (iforce_eval == 1)
THEN
1021 cdft_control_source%do_et = .false.
1022 cdft_control_source%calculate_metric = .false.
1024 cdft_control_target%do_et = .false.
1025 cdft_control_target%calculate_metric = .false.
1029 IF (iforce_eval == nforce_eval .AND. first_call) first_call = .false.
1030 CALL timestop(handle)
1032 END SUBROUTINE mixed_cdft_transfer_weight
1041 SUBROUTINE mixed_cdft_set_flags(force_env)
1044 CHARACTER(len=*),
PARAMETER :: routinen =
'mixed_cdft_set_flags'
1046 INTEGER :: handle, iforce_eval, nforce_eval
1047 LOGICAL,
SAVE :: first_call = .true.
1055 NULLIFY (mixed_cdft, dft_control, force_env_qs, qs_env, mixed_env, cdft_control)
1056 mixed_env => force_env%mixed_env
1058 CALL timeset(routinen, handle)
1059 nforce_eval =
SIZE(force_env%sub_force_env)
1060 DO iforce_eval = 1, nforce_eval
1061 IF (.NOT.
ASSOCIATED(force_env%sub_force_env(iforce_eval)%force_env)) cycle
1062 SELECT CASE (force_env%sub_force_env(iforce_eval)%force_env%in_use)
1064 force_env_qs => force_env%sub_force_env(iforce_eval)%force_env
1068 IF (.NOT. force_env%mixed_env%do_mixed_qmmm_cdft)
THEN
1071 qs_env => force_env_qs%qmmm_env%qs_env
1075 CALL get_qs_env(qs_env, dft_control=dft_control)
1076 cdft_control => dft_control%qs_control%cdft_control
1077 cdft_control%external_control = .false.
1078 cdft_control%need_pot = .true.
1079 cdft_control%transfer_pot = .false.
1080 IF (first_call)
THEN
1081 cdft_control%first_iteration = .true.
1083 cdft_control%first_iteration = .false.
1086 IF (mixed_env%do_mixed_et)
THEN
1087 IF (
modulo(mixed_cdft%sim_step, mixed_env%et_freq) == 0)
THEN
1088 cdft_control%do_et = .true.
1089 cdft_control%calculate_metric = mixed_cdft%calculate_metric
1091 cdft_control%do_et = .false.
1092 cdft_control%calculate_metric = .false.
1096 mixed_cdft%sim_step = mixed_cdft%sim_step + 1
1097 IF (first_call) first_call = .false.
1098 CALL timestop(handle)
1100 END SUBROUTINE mixed_cdft_set_flags
1111 CHARACTER(len=*),
PARAMETER :: routinen =
'mixed_cdft_calculate_coupling'
1115 cpassert(
ASSOCIATED(force_env))
1116 CALL timeset(routinen, handle)
1122 CALL mixed_cdft_interaction_matrices(force_env)
1124 CALL mixed_cdft_calculate_coupling_low(force_env)
1128 CALL mixed_cdft_block_diag(force_env)
1130 CALL mixed_cdft_configuration_interaction(force_env)
1133 CALL timestop(handle)
1143 SUBROUTINE mixed_cdft_interaction_matrices(force_env)
1146 CHARACTER(len=*),
PARAMETER :: routinen =
'mixed_cdft_interaction_matrices'
1148 INTEGER :: check_ao(2), check_mo(2), handle, iforce_eval, ipermutation, ispin, istate, ivar, &
1149 j, jstate, k, moeigvalunit, mounit, nao, ncol_local, nforce_eval, nmo, npermutations, &
1150 nrow_local, nspins, nvar
1151 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: ncol_mo, nrow_mo
1152 INTEGER,
ALLOCATABLE,
DIMENSION(:, :) :: homo
1153 LOGICAL :: nelectron_mismatch, print_mo, &
1154 print_mo_eigval, should_scale, &
1156 REAL(kind=
dp) :: c(2), eps_occupied, nelectron_tot, &
1158 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: coupling_nonortho, eigenv, energy, sda
1159 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: h_mat, s_det, s_mat, strength, tmp_mat, &
1160 w_diagonal, wad, wda
1161 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :, :) :: a, b
1162 REAL(kind=
dp),
DIMENSION(:),
POINTER :: mo_eigval
1164 TYPE(
cp_fm_type) :: inverse_mat, tinverse, tmp2
1165 TYPE(
cp_fm_type),
ALLOCATABLE,
DIMENSION(:) :: mo_overlap
1166 TYPE(
cp_fm_type),
ALLOCATABLE,
DIMENSION(:, :, :) :: w_matrix_mo
1167 TYPE(
cp_fm_type),
DIMENSION(:, :),
POINTER :: mixed_mo_coeff
1169 TYPE(
dbcsr_p_type),
DIMENSION(:, :),
POINTER :: density_matrix, density_matrix_diff, &
1180 NULLIFY (force_env_section, print_section, mixed_cdft_section, &
1181 mixed_env, mixed_cdft, qs_env, dft_control, fm_struct_mo, &
1182 density_matrix_diff, mo_mo_fmstruct, &
1183 mixed_mo_coeff, mixed_matrix_s, &
1184 density_matrix, energy_qs, w_matrix, mo_eigval)
1186 cpassert(
ASSOCIATED(force_env))
1187 CALL timeset(routinen, handle)
1189 force_env_section=force_env_section)
1190 mixed_env => force_env%mixed_env
1191 nforce_eval =
SIZE(force_env%sub_force_env)
1200 print_mo_eigval = .true.
1201 moeigvalunit =
cp_print_key_unit_nr(logger, print_section, extension=
'.moOverlapEigval', on_file=.true.)
1203 print_mo_eigval = .false.
1207 cpassert(
ASSOCIATED(mixed_cdft))
1208 cpassert(
ASSOCIATED(mixed_cdft%matrix%mixed_mo_coeff))
1209 cpassert(
ASSOCIATED(mixed_cdft%matrix%w_matrix))
1210 cpassert(
ASSOCIATED(mixed_cdft%matrix%mixed_matrix_s))
1211 mixed_mo_coeff => mixed_cdft%matrix%mixed_mo_coeff
1212 w_matrix => mixed_cdft%matrix%w_matrix
1213 mixed_matrix_s => mixed_cdft%matrix%mixed_matrix_s
1214 IF (mixed_cdft%calculate_metric)
THEN
1215 cpassert(
ASSOCIATED(mixed_cdft%matrix%density_matrix))
1216 density_matrix => mixed_cdft%matrix%density_matrix
1219 nvar =
SIZE(w_matrix, 2)
1220 nspins =
SIZE(mixed_mo_coeff, 2)
1222 ALLOCATE (nrow_mo(nspins), ncol_mo(nspins))
1223 DO ispin = 1, nspins
1224 CALL cp_fm_get_info(mixed_mo_coeff(1, ispin), ncol_global=check_mo(1), nrow_global=check_ao(1))
1225 DO iforce_eval = 2, nforce_eval
1226 CALL cp_fm_get_info(mixed_mo_coeff(iforce_eval, ispin), ncol_global=check_mo(2), nrow_global=check_ao(2))
1227 IF (check_ao(1) /= check_ao(2)) &
1228 CALL cp_abort(__location__, &
1229 "The number of atomic orbitals must be the same in every CDFT state.")
1230 IF (check_mo(1) /= check_mo(2)) &
1231 CALL cp_abort(__location__, &
1232 "The number of molecular orbitals must be the same in every CDFT state.")
1236 npermutations = nforce_eval*(nforce_eval - 1)/2
1237 ALLOCATE (w_matrix_mo(nforce_eval, nforce_eval, nvar))
1238 ALLOCATE (mo_overlap(npermutations), s_det(npermutations, nspins))
1239 ALLOCATE (a(nspins, nvar, npermutations), b(nspins, nvar, npermutations))
1242 IF (mixed_cdft%calculate_metric)
THEN
1243 ALLOCATE (density_matrix_diff(npermutations, nspins))
1244 DO ispin = 1, nspins
1245 DO ipermutation = 1, npermutations
1246 NULLIFY (density_matrix_diff(ipermutation, ispin)%matrix)
1247 CALL dbcsr_init_p(density_matrix_diff(ipermutation, ispin)%matrix)
1249 CALL dbcsr_copy(density_matrix_diff(ipermutation, ispin)%matrix, &
1250 density_matrix(istate, ispin)%matrix, name=
"DENSITY_MATRIX")
1255 uniform_occupation = .NOT.
ALLOCATED(mixed_cdft%occupations)
1256 should_scale = .false.
1257 IF (.NOT. uniform_occupation)
THEN
1258 ALLOCATE (homo(nforce_eval, nspins))
1261 IF (eps_occupied .GT. 1.0_dp .OR. eps_occupied .LT. 0.0_dp) &
1262 CALL cp_abort(__location__, &
1263 "Keyword EPS_OCCUPIED only accepts values between 0.0 and 1.0")
1264 IF (mixed_cdft%eps_svd == 0.0_dp) &
1265 CALL cp_warn(__location__, &
1266 "The usage of SVD based matrix inversions with fractionally occupied "// &
1267 "orbitals is strongly recommended to screen nearly orthogonal states.")
1268 CALL section_vals_val_get(mixed_cdft_section,
"SCALE_WITH_OCCUPATION_NUMBERS", l_val=should_scale)
1271 DO ispin = 1, nspins
1274 NULLIFY (fm_struct_mo, mo_mo_fmstruct)
1275 CALL cp_fm_get_info(mixed_mo_coeff(1, ispin), ncol_global=ncol_mo(ispin), nrow_global=nrow_mo(ispin))
1276 nao = nrow_mo(ispin)
1277 IF (uniform_occupation)
THEN
1278 nmo = ncol_mo(ispin)
1280 nmo = ncol_mo(ispin)
1282 homo(:, ispin) = nmo
1283 DO istate = 1, nforce_eval
1285 IF (mixed_cdft%occupations(istate, ispin)%array(j) .GE. eps_occupied)
THEN
1286 homo(istate, ispin) = j
1294 nmo = maxval(homo(:, ispin))
1296 nelectron_mismatch = .false.
1297 nelectron_tot = sum(mixed_cdft%occupations(1, ispin)%array(1:nmo))
1298 DO istate = 2, nforce_eval
1299 IF (abs(sum(mixed_cdft%occupations(istate, ispin)%array(1:nmo)) - nelectron_tot) .GT. 1.0e-4_dp) &
1300 nelectron_mismatch = .true.
1302 IF (any(homo(:, ispin) /= nmo))
THEN
1303 IF (ispin == 1)
THEN
1304 CALL cp_warn(__location__, &
1305 "The number of occupied alpha MOs is not constant across all CDFT states. "// &
1306 "Calculation proceeds but the results will likely be meaningless.")
1308 CALL cp_warn(__location__, &
1309 "The number of occupied beta MOs is not constant across all CDFT states. "// &
1310 "Calculation proceeds but the results will likely be meaningless.")
1312 ELSE IF (nelectron_mismatch)
THEN
1313 IF (ispin == 1)
THEN
1314 CALL cp_warn(__location__, &
1315 "The number of alpha electrons is not constant across all CDFT states. "// &
1316 "Calculation proceeds but the results will likely be meaningless.")
1318 CALL cp_warn(__location__, &
1319 "The number of beta electrons is not constant across all CDFT states. "// &
1320 "Calculation proceeds but the results will likely be meaningless.")
1325 context=mixed_cdft%blacs_env, para_env=force_env%para_env)
1327 context=mixed_cdft%blacs_env, para_env=force_env%para_env)
1329 CALL cp_fm_create(matrix=tmp2, matrix_struct=fm_struct_mo, &
1330 name=
"ET_TMP_"//trim(adjustl(
cp_to_string(ispin)))//
"_MATRIX")
1332 CALL cp_fm_create(matrix=inverse_mat, matrix_struct=mo_mo_fmstruct, &
1333 name=
"INVERSE_"//trim(adjustl(
cp_to_string(ispin)))//
"_MATRIX")
1334 CALL cp_fm_create(matrix=tinverse, matrix_struct=mo_mo_fmstruct, &
1335 name=
"T_INVERSE_"//trim(adjustl(
cp_to_string(ispin)))//
"_MATRIX")
1336 DO istate = 1, npermutations
1337 CALL cp_fm_create(matrix=mo_overlap(istate), matrix_struct=mo_mo_fmstruct, &
1338 name=
"MO_OVERLAP_"//trim(adjustl(
cp_to_string(istate)))//
"_"// &
1342 DO istate = 1, nforce_eval
1343 DO jstate = 1, nforce_eval
1344 IF (istate == jstate) cycle
1345 CALL cp_fm_create(matrix=w_matrix_mo(istate, jstate, ivar), matrix_struct=mo_mo_fmstruct, &
1346 name=
"W_"//trim(adjustl(
cp_to_string(istate)))//
"_"// &
1354 IF (.NOT. uniform_occupation)
THEN
1355 DO iforce_eval = 1, nforce_eval
1356 CALL cp_fm_to_fm(mixed_mo_coeff(iforce_eval, ispin), tmp2, nmo, 1, 1)
1358 CALL cp_fm_create(mixed_mo_coeff(iforce_eval, ispin), &
1359 matrix_struct=tmp2%matrix_struct, &
1360 name=
"MO_COEFF_"//trim(adjustl(
cp_to_string(iforce_eval)))//
"_" &
1362 CALL cp_fm_to_fm(tmp2, mixed_mo_coeff(iforce_eval, ispin))
1365 mixed_cdft%occupations(iforce_eval, ispin)%array(1:nmo))
1366 DEALLOCATE (mixed_cdft%occupations(iforce_eval, ispin)%array)
1371 DO istate = 1, nforce_eval
1372 DO jstate = istate + 1, nforce_eval
1373 ipermutation = ipermutation + 1
1375 tmp2, nmo, 1.0_dp, 0.0_dp)
1377 mixed_mo_coeff(jstate, ispin), &
1378 tmp2, 0.0_dp, mo_overlap(ipermutation))
1381 "# MO overlap matrix (step "//trim(adjustl(
cp_to_string(mixed_cdft%sim_step)))// &
1382 "): CDFT states "//trim(adjustl(
cp_to_string(istate)))//
" and "// &
1389 DO jstate = 1, nforce_eval
1390 DO istate = 1, nforce_eval
1391 IF (istate == jstate) cycle
1394 mixed_mo_coeff(istate, ispin), &
1395 tmp2, nmo, 1.0_dp, 0.0_dp)
1397 mixed_mo_coeff(jstate, ispin), &
1398 tmp2, 0.0_dp, w_matrix_mo(istate, jstate, ivar))
1402 DO ipermutation = 1, npermutations
1405 IF (print_mo_eigval)
THEN
1407 CALL cp_fm_invert(mo_overlap(ipermutation), inverse_mat, &
1408 s_det(ipermutation, ispin), eps_svd=mixed_cdft%eps_svd, &
1410 IF (moeigvalunit > 0)
THEN
1411 IF (mixed_cdft%eps_svd == 0.0_dp)
THEN
1412 WRITE (moeigvalunit,
'(A,I2,A,I2,A,I1,A)') &
1413 "# MO Overlap matrix eigenvalues for CDFT states ", istate,
" and ", jstate, &
1414 " (spin ", ispin,
")"
1416 WRITE (moeigvalunit,
'(A,I2,A,I2,A,I1,A)') &
1417 "# MO Overlap matrix singular values for CDFT states ", istate,
" and ", jstate, &
1418 " (spin ", ispin,
")"
1420 WRITE (moeigvalunit,
'(A1, A9, A12)')
"#",
"Index", adjustl(
"Value")
1421 DO j = 1,
SIZE(mo_eigval)
1422 WRITE (moeigvalunit,
'(I10, F12.8)') j, mo_eigval(j)
1425 DEALLOCATE (mo_eigval)
1427 CALL cp_fm_invert(mo_overlap(ipermutation), inverse_mat, &
1428 s_det(ipermutation, ispin), eps_svd=mixed_cdft%eps_svd)
1430 CALL cp_fm_get_info(inverse_mat, nrow_local=nrow_local, ncol_local=ncol_local)
1432 DO j = 1, ncol_local
1433 DO k = 1, nrow_local
1435 b(ispin, ivar, ipermutation) = b(ispin, ivar, ipermutation) + &
1436 w_matrix_mo(jstate, istate, ivar)%local_data(k, j)* &
1437 inverse_mat%local_data(k, j)
1443 DO j = 1, ncol_local
1444 DO k = 1, nrow_local
1446 a(ispin, ivar, ipermutation) = a(ispin, ivar, ipermutation) + &
1447 w_matrix_mo(istate, jstate, ivar)%local_data(k, j)* &
1448 tinverse%local_data(k, j)
1454 SELECT CASE (mixed_cdft%constraint_type(ivar, istate))
1458 IF (ispin == 2) a(ispin, ivar, ipermutation) = -a(ispin, ivar, ipermutation)
1461 IF (ispin == 2) a(ispin, ivar, ipermutation) = 0.0_dp
1464 IF (ispin == 1) a(ispin, ivar, ipermutation) = 0.0_dp
1466 cpabort(
"Unknown constraint type.")
1468 SELECT CASE (mixed_cdft%constraint_type(ivar, jstate))
1472 IF (ispin == 2) b(ispin, ivar, ipermutation) = -b(ispin, ivar, ipermutation)
1475 IF (ispin == 2) b(ispin, ivar, ipermutation) = 0.0_dp
1478 IF (ispin == 1) b(ispin, ivar, ipermutation) = 0.0_dp
1480 cpabort(
"Unknown constraint type.")
1484 IF (mixed_cdft%calculate_metric) &
1485 CALL dbcsr_add(density_matrix_diff(ipermutation, ispin)%matrix, &
1486 density_matrix(jstate, ispin)%matrix, -1.0_dp, 1.0_dp)
1488 CALL force_env%para_env%sum(a(ispin, :, ipermutation))
1489 CALL force_env%para_env%sum(b(ispin, :, ipermutation))
1494 DO jstate = 1, nforce_eval
1495 DO istate = 1, nforce_eval
1496 IF (istate == jstate) cycle
1501 DO ipermutation = 1, npermutations
1507 DEALLOCATE (mo_overlap)
1508 DEALLOCATE (w_matrix_mo)
1509 IF (.NOT. uniform_occupation)
THEN
1511 DEALLOCATE (mixed_cdft%occupations)
1515 "MIXED%MIXED_CDFT%PRINT%PROGRAM_RUN_INFO", on_file=.true.)
1516 IF (print_mo_eigval) &
1518 "MIXED%MIXED_CDFT%PRINT%PROGRAM_RUN_INFO", on_file=.true.)
1520 ALLOCATE (wda(nvar, npermutations))
1521 ALLOCATE (sda(npermutations))
1522 IF (.NOT. mixed_cdft%identical_constraints)
ALLOCATE (wad(nvar, npermutations))
1523 DO ipermutation = 1, npermutations
1524 IF (nspins == 2)
THEN
1525 sda(ipermutation) = abs(s_det(ipermutation, 1)*s_det(ipermutation, 2))
1527 sda(ipermutation) = s_det(ipermutation, 1)**2
1531 IF (mixed_cdft%identical_constraints)
THEN
1532 wda(ivar, ipermutation) = (sum(a(:, ivar, ipermutation)) + sum(b(:, ivar, ipermutation)))* &
1533 sda(ipermutation)/2.0_dp
1535 wda(ivar, ipermutation) = sum(a(:, ivar, ipermutation))*sda(ipermutation)
1536 wad(ivar, ipermutation) = sum(b(:, ivar, ipermutation))*sda(ipermutation)
1540 DEALLOCATE (a, b, s_det)
1542 ALLOCATE (w_diagonal(nvar, nforce_eval), strength(nvar, nforce_eval), energy(nforce_eval))
1544 DO iforce_eval = 1, nforce_eval
1545 strength(:, iforce_eval) = mixed_env%strength(iforce_eval, :)
1548 DO iforce_eval = 1, nforce_eval
1549 IF (.NOT.
ASSOCIATED(force_env%sub_force_env(iforce_eval)%force_env)) cycle
1550 IF (force_env%mixed_env%do_mixed_qmmm_cdft)
THEN
1551 qs_env => force_env%sub_force_env(iforce_eval)%force_env%qmmm_env%qs_env
1553 CALL force_env_get(force_env%sub_force_env(iforce_eval)%force_env, qs_env=qs_env)
1555 CALL get_qs_env(qs_env, energy=energy_qs, dft_control=dft_control)
1556 IF (force_env%sub_force_env(iforce_eval)%force_env%para_env%is_source())
THEN
1557 w_diagonal(:, iforce_eval) = dft_control%qs_control%cdft_control%value(:)
1558 energy(iforce_eval) = energy_qs%total
1561 CALL force_env%para_env%sum(w_diagonal)
1562 CALL force_env%para_env%sum(energy)
1564 energy=energy, strength=strength)
1567 ALLOCATE (s_mat(nforce_eval, nforce_eval))
1568 DO istate = 1, nforce_eval
1569 s_mat(istate, istate) = 1.0_dp
1571 DO ipermutation = 1, npermutations
1573 s_mat(istate, jstate) = sda(ipermutation)
1574 s_mat(jstate, istate) = sda(ipermutation)
1578 ALLOCATE (eigenv(nforce_eval), tmp_mat(nforce_eval, nforce_eval))
1581 DO istate = 1, nforce_eval
1582 IF (eigenv(istate) .LT. 1.0e-14_dp)
THEN
1584 eigenv(istate) = 1.0e-14_dp
1585 CALL cp_warn(__location__, &
1586 "The overlap matrix is numerically nearly singular. "// &
1587 "Calculation proceeds but the results might be meaningless.")
1589 tmp_mat(istate, istate) = 1.0_dp/sqrt(eigenv(istate))
1591 tmp_mat(:, :) = matmul(tmp_mat, transpose(s_mat))
1592 s_mat(:, :) = matmul(s_mat, tmp_mat)
1594 DEALLOCATE (eigenv, tmp_mat, s_mat)
1596 ALLOCATE (h_mat(nforce_eval, nforce_eval))
1597 IF (mixed_cdft%nonortho_coupling)
ALLOCATE (coupling_nonortho(npermutations))
1598 DO istate = 1, nforce_eval
1599 h_mat(istate, istate) = energy(istate)
1601 DO ipermutation = 1, npermutations
1607 sum_b(1) = sum_b(1) + strength(ivar, jstate)*w_diagonal(ivar, jstate)
1609 sum_a(1) = sum_a(1) + strength(ivar, istate)*w_diagonal(ivar, istate)
1610 IF (mixed_cdft%identical_constraints)
THEN
1612 sum_b(2) = sum_b(2) + strength(ivar, jstate)*wda(ivar, ipermutation)
1614 sum_a(2) = sum_a(2) + strength(ivar, istate)*wda(ivar, ipermutation)
1617 sum_b(2) = sum_b(2) + strength(ivar, jstate)*wad(ivar, ipermutation)
1619 sum_a(2) = sum_a(2) + strength(ivar, istate)*wda(ivar, ipermutation)
1624 c(1) = (energy(jstate) + sum_b(1))*sda(ipermutation) - sum_b(2)
1626 c(2) = (energy(istate) + sum_a(1))*sda(ipermutation) - sum_a(2)
1628 h_mat(istate, jstate) = (c(1) + c(2))*0.5_dp
1629 h_mat(jstate, istate) = h_mat(istate, jstate)
1630 IF (mixed_cdft%nonortho_coupling) coupling_nonortho(ipermutation) = h_mat(istate, jstate)
1633 DEALLOCATE (h_mat, w_diagonal, wda, strength, energy, sda)
1634 IF (
ALLOCATED(wad))
DEALLOCATE (wad)
1635 IF (mixed_cdft%nonortho_coupling)
THEN
1637 DEALLOCATE (coupling_nonortho)
1640 IF (mixed_cdft%calculate_metric)
CALL mixed_cdft_calculate_metric(force_env, mixed_cdft, density_matrix_diff, ncol_mo)
1643 IF (mixed_cdft%wfn_overlap_method)
THEN
1644 IF (.NOT. uniform_occupation) &
1645 CALL cp_abort(__location__, &
1646 "Wavefunction overlap method supports only uniformly occupied MOs.")
1647 CALL mixed_cdft_wfn_overlap_method(force_env, mixed_cdft, ncol_mo, nrow_mo)
1650 DEALLOCATE (nrow_mo, ncol_mo)
1652 CALL timestop(handle)
1654 END SUBROUTINE mixed_cdft_interaction_matrices
1662 SUBROUTINE mixed_cdft_calculate_coupling_low(force_env)
1665 CHARACTER(len=*),
PARAMETER :: routinen =
'mixed_cdft_calculate_coupling_low'
1667 INTEGER :: handle, ipermutation, istate, jstate, &
1668 nforce_eval, npermutations, nvar
1669 LOGICAL :: use_lowdin, use_rotation
1670 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: coupling_lowdin, coupling_rotation, &
1672 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: tmp_mat, w_mat
1675 NULLIFY (mixed_cdft)
1676 cpassert(
ASSOCIATED(force_env))
1677 CALL get_mixed_env(force_env%mixed_env, cdft_control=mixed_cdft)
1678 CALL timeset(routinen, handle)
1679 cpassert(
ASSOCIATED(mixed_cdft))
1680 cpassert(
ALLOCATED(mixed_cdft%results%W_diagonal))
1681 cpassert(
ALLOCATED(mixed_cdft%results%Wda))
1682 cpassert(
ALLOCATED(mixed_cdft%results%S_minushalf))
1683 cpassert(
ALLOCATED(mixed_cdft%results%H))
1688 nforce_eval =
SIZE(mixed_cdft%results%H, 1)
1689 nvar =
SIZE(mixed_cdft%results%Wda, 1)
1690 npermutations = nforce_eval*(nforce_eval - 1)/2
1691 ALLOCATE (tmp_mat(nforce_eval, nforce_eval))
1692 IF (nvar == 1 .AND. mixed_cdft%identical_constraints)
THEN
1693 use_rotation = .true.
1694 use_lowdin = mixed_cdft%use_lowdin
1696 use_rotation = .false.
1700 IF (use_rotation)
THEN
1702 ALLOCATE (w_mat(nforce_eval, nforce_eval), coupling_rotation(npermutations))
1703 ALLOCATE (eigenv(nforce_eval))
1705 DO istate = 1, nforce_eval
1706 w_mat(istate, istate) = sum(mixed_cdft%results%W_diagonal(:, istate))
1709 DO ipermutation = 1, npermutations
1711 w_mat(istate, jstate) = sum(mixed_cdft%results%Wda(:, ipermutation))
1712 w_mat(jstate, istate) = w_mat(istate, jstate)
1716 tmp_mat(:, :) = matmul(w_mat, mixed_cdft%results%S_minushalf)
1717 w_mat(:, :) = matmul(mixed_cdft%results%S_minushalf, tmp_mat)
1719 tmp_mat(:, :) = matmul(mixed_cdft%results%S_minushalf, w_mat)
1721 w_mat(:, :) = matmul(mixed_cdft%results%H, tmp_mat)
1722 w_mat(:, :) = matmul(transpose(tmp_mat), w_mat)
1723 DO ipermutation = 1, npermutations
1725 coupling_rotation(ipermutation) = w_mat(istate, jstate)
1728 DEALLOCATE (w_mat, coupling_rotation, eigenv)
1731 IF (use_lowdin)
THEN
1732 ALLOCATE (coupling_lowdin(npermutations))
1733 tmp_mat(:, :) = matmul(mixed_cdft%results%H, mixed_cdft%results%S_minushalf)
1735 tmp_mat(:, :) = matmul(mixed_cdft%results%S_minushalf, tmp_mat)
1736 DO ipermutation = 1, npermutations
1738 coupling_lowdin(ipermutation) = tmp_mat(istate, jstate)
1741 DEALLOCATE (coupling_lowdin)
1743 DEALLOCATE (tmp_mat)
1744 CALL timestop(handle)
1746 END SUBROUTINE mixed_cdft_calculate_coupling_low
1754 SUBROUTINE mixed_cdft_configuration_interaction(force_env)
1757 CHARACTER(len=*),
PARAMETER :: routinen =
'mixed_cdft_configuration_interaction'
1759 INTEGER :: handle, info, iounit, istate, ivar, &
1760 nforce_eval, work_array_size
1761 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: eigenv, work
1762 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: h_mat, h_mat_copy, s_mat, s_mat_copy
1763 REAL(kind=
dp),
EXTERNAL :: dnrm2
1770 NULLIFY (logger, force_env_section, print_section, mixed_cdft)
1772 cpassert(
ASSOCIATED(force_env))
1773 CALL get_mixed_env(force_env%mixed_env, cdft_control=mixed_cdft)
1774 cpassert(
ASSOCIATED(mixed_cdft))
1776 IF (.NOT. mixed_cdft%do_ci)
RETURN
1779 CALL timeset(routinen, handle)
1781 force_env_section=force_env_section)
1785 cpassert(
ALLOCATED(mixed_cdft%results%S))
1786 cpassert(
ALLOCATED(mixed_cdft%results%H))
1787 nforce_eval =
SIZE(mixed_cdft%results%S, 1)
1788 ALLOCATE (s_mat(nforce_eval, nforce_eval), h_mat(nforce_eval, nforce_eval))
1789 ALLOCATE (eigenv(nforce_eval))
1790 s_mat(:, :) = mixed_cdft%results%S(:, :)
1791 h_mat(:, :) = mixed_cdft%results%H(:, :)
1795 ALLOCATE (h_mat_copy(nforce_eval, nforce_eval), s_mat_copy(nforce_eval, nforce_eval))
1796 h_mat_copy(:, :) = h_mat(:, :)
1797 s_mat_copy(:, :) = s_mat(:, :)
1798 CALL dsygv(1,
'V',
'U', nforce_eval, h_mat_copy, nforce_eval, s_mat_copy, nforce_eval, eigenv, work, -1, info)
1799 work_array_size = nint(work(1))
1800 DEALLOCATE (h_mat_copy, s_mat_copy)
1803 ALLOCATE (work(work_array_size))
1807 CALL dsygv(1,
'V',
'U', nforce_eval, h_mat, nforce_eval, s_mat, nforce_eval, eigenv, work, work_array_size, info)
1809 IF (info > nforce_eval)
THEN
1810 cpabort(
"Matrix S is not positive definite")
1812 cpabort(
"Diagonalization of H matrix failed.")
1817 DO ivar = 1, nforce_eval
1818 h_mat(:, ivar) = h_mat(:, ivar)/dnrm2(nforce_eval, h_mat(:, ivar), 1)
1821 IF (iounit > 0)
THEN
1822 WRITE (iounit,
'(/,T3,A)')
'------------------ CDFT Configuration Interaction (CDFT-CI) ------------------'
1823 DO ivar = 1, nforce_eval
1825 WRITE (iounit,
'(T3,A,T58,(3X,F20.14))')
'Ground state energy:', eigenv(ivar)
1827 WRITE (iounit,
'(/,T3,A,I2,A,T58,(3X,F20.14))')
'Excited state (', ivar - 1,
' ) energy:', eigenv(ivar)
1829 DO istate = 1, nforce_eval, 2
1830 IF (istate == 1)
THEN
1831 WRITE (iounit,
'(T3,A,T54,(3X,2F12.6))') &
1832 'Expansion coefficients:', h_mat(istate, ivar), h_mat(istate + 1, ivar)
1833 ELSE IF (istate .LT. nforce_eval)
THEN
1834 WRITE (iounit,
'(T54,(3X,2F12.6))') h_mat(istate, ivar), h_mat(istate + 1, ivar)
1836 WRITE (iounit,
'(T54,(3X,F12.6))') h_mat(istate, ivar)
1840 WRITE (iounit,
'(T3,A)') &
1841 '------------------------------------------------------------------------------'
1843 DEALLOCATE (s_mat, h_mat, eigenv)
1845 "MIXED%MIXED_CDFT%PRINT%PROGRAM_RUN_INFO")
1846 CALL timestop(handle)
1848 END SUBROUTINE mixed_cdft_configuration_interaction
1857 SUBROUTINE mixed_cdft_block_diag(force_env)
1860 CHARACTER(len=*),
PARAMETER :: routinen =
'mixed_cdft_block_diag'
1862 INTEGER :: handle, i, iounit, irecursion, j, n, &
1863 nblk, nforce_eval, nrecursion
1864 LOGICAL :: ignore_excited
1867 TYPE(
cp_2d_r_p_type),
ALLOCATABLE,
DIMENSION(:) :: h_block, s_block
1874 NULLIFY (logger, force_env_section, print_section, mixed_cdft)
1876 cpassert(
ASSOCIATED(force_env))
1877 CALL get_mixed_env(force_env%mixed_env, cdft_control=mixed_cdft)
1878 cpassert(
ASSOCIATED(mixed_cdft))
1880 IF (.NOT. mixed_cdft%block_diagonalize)
RETURN
1883 CALL timeset(routinen, handle)
1885 cpassert(
ALLOCATED(mixed_cdft%results%S))
1886 cpassert(
ALLOCATED(mixed_cdft%results%H))
1887 nforce_eval =
SIZE(mixed_cdft%results%S, 1)
1890 force_env_section=force_env_section)
1897 DO irecursion = 1, nrecursion
1899 IF (iounit > 0 .AND. irecursion == 1)
THEN
1900 WRITE (iounit,
'(/,T3,A)')
'-------------------------- CDFT BLOCK DIAGONALIZATION ------------------------'
1901 WRITE (iounit,
'(T3,A)')
'Block diagonalizing the mixed CDFT Hamiltonian'
1902 WRITE (iounit,
'(T3,A,I3)')
'Number of blocks:', nblk
1903 WRITE (iounit,
'(T3,A,L3)')
'Ignoring excited states within blocks:', ignore_excited
1904 WRITE (iounit,
'(/,T3,A)')
'List of CDFT states for each block'
1906 WRITE (iounit,
'(T6,A,I3,A,6I3)')
'Block', i,
':', (blocks(i)%array(j), j=1,
SIZE(blocks(i)%array))
1910 IF (irecursion > 1)
THEN
1912 ALLOCATE (blocks(nblk))
1915 NULLIFY (blocks(i)%array)
1916 ALLOCATE (blocks(i)%array(2))
1917 blocks(i)%array = (/j, j + 1/)
1921 IF (iounit > 0)
THEN
1922 WRITE (iounit,
'(/, T3,A)')
'Recursive block diagonalization of the mixed CDFT Hamiltonian'
1923 WRITE (iounit,
'(T6,A)')
'Block diagonalization is continued until only two matrix blocks remain.'
1924 WRITE (iounit,
'(T6,A)')
'The new blocks are formed by collecting pairs of blocks from the previous'
1925 WRITE (iounit,
'(T6,A)')
'block diagonalized matrix in ascending order.'
1926 WRITE (iounit,
'(/,T3,A,I3,A,I3)')
'Recursion step:', irecursion - 1,
' of ', nrecursion - 1
1927 WRITE (iounit,
'(/,T3,A)')
'List of old block indices for each new block'
1929 WRITE (iounit,
'(T6,A,I3,A,6I3)')
'Block', i,
':', (blocks(i)%array(j), j=1,
SIZE(blocks(i)%array))
1938 IF (ignore_excited)
THEN
1946 DEALLOCATE (h_block(i)%array)
1947 DEALLOCATE (s_block(i)%array)
1948 DEALLOCATE (eigenvalues(i)%array)
1949 DEALLOCATE (blocks(i)%array)
1951 DEALLOCATE (h_block, s_block, eigenvalues, blocks)
1954 WRITE (iounit,
'(T3,A)') &
1955 '------------------------------------------------------------------------------'
1957 "MIXED%MIXED_CDFT%PRINT%PROGRAM_RUN_INFO")
1958 CALL timestop(handle)
1960 END SUBROUTINE mixed_cdft_block_diag
1971 SUBROUTINE mixed_cdft_calculate_metric(force_env, mixed_cdft, density_matrix_diff, ncol_mo)
1974 TYPE(
dbcsr_p_type),
DIMENSION(:, :),
POINTER :: density_matrix_diff
1975 INTEGER,
DIMENSION(:) :: ncol_mo
1977 CHARACTER(len=*),
PARAMETER :: routinen =
'mixed_cdft_calculate_metric'
1979 INTEGER :: handle, ipermutation, ispin, j, &
1980 nforce_eval, npermutations, nspins
1981 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: evals
1982 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: metric
1985 CALL timeset(routinen, handle)
1986 nforce_eval =
SIZE(mixed_cdft%results%H, 1)
1987 npermutations = nforce_eval*(nforce_eval - 1)/2
1988 nspins =
SIZE(density_matrix_diff, 2)
1989 ALLOCATE (metric(npermutations, nspins))
1991 CALL dbcsr_create(e_vectors, template=density_matrix_diff(1, 1)%matrix)
1992 DO ispin = 1, nspins
1993 ALLOCATE (evals(ncol_mo(ispin)))
1994 DO ipermutation = 1, npermutations
1997 CALL dbcsr_scale(density_matrix_diff(ipermutation, 1)%matrix, alpha_scalar=0.5_dp)
1999 CALL cp_dbcsr_syevd(density_matrix_diff(ipermutation, ispin)%matrix, e_vectors, evals, &
2000 para_env=force_env%para_env, blacs_env=mixed_cdft%blacs_env)
2002 DO j = 1, ncol_mo(ispin)
2003 metric(ipermutation, ispin) = metric(ipermutation, ispin) + (evals(j)**2 - evals(j)**4)
2009 DEALLOCATE (density_matrix_diff)
2010 metric(:, :) = metric(:, :)/4.0_dp
2013 CALL timestop(handle)
2015 END SUBROUTINE mixed_cdft_calculate_metric
2026 SUBROUTINE mixed_cdft_wfn_overlap_method(force_env, mixed_cdft, ncol_mo, nrow_mo)
2029 INTEGER,
DIMENSION(:) :: ncol_mo, nrow_mo
2031 CHARACTER(len=*),
PARAMETER :: routinen =
'mixed_cdft_wfn_overlap_method'
2033 CHARACTER(LEN=default_path_length) :: file_name
2034 INTEGER :: handle, ipermutation, ispin, istate, &
2035 jstate, nao, nforce_eval, nmo, &
2036 npermutations, nspins
2037 LOGICAL :: exist, natom_mismatch
2038 REAL(kind=
dp) :: energy_diff, maxocc, sda
2039 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: coupling_wfn
2040 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :, :) :: overlaps
2043 TYPE(
cp_fm_type) :: inverse_mat, mo_overlap_wfn, mo_tmp
2044 TYPE(
cp_fm_type),
DIMENSION(:, :),
POINTER :: mixed_mo_coeff
2048 TYPE(
mo_set_type),
ALLOCATABLE,
DIMENSION(:) :: mo_set
2050 TYPE(
qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
2053 NULLIFY (mixed_cdft_section, subsys_mix, particle_set, qs_kind_set, atomic_kind_set, &
2054 mixed_mo_coeff, mixed_matrix_s, force_env_section)
2057 CALL timeset(routinen, handle)
2058 nforce_eval =
SIZE(mixed_cdft%results%H, 1)
2059 npermutations = nforce_eval*(nforce_eval - 1)/2
2060 nspins =
SIZE(nrow_mo)
2061 mixed_mo_coeff => mixed_cdft%matrix%mixed_mo_coeff
2062 mixed_matrix_s => mixed_cdft%matrix%mixed_matrix_s
2064 force_env_section=force_env_section)
2066 ALLOCATE (mo_set(nspins))
2067 IF (nspins == 2)
THEN
2072 DO ispin = 1, nspins
2073 nao = nrow_mo(ispin)
2074 nmo = ncol_mo(ispin)
2076 CALL allocate_mo_set(mo_set(ispin), nao=nao, nmo=nmo, nelectron=int(maxocc*nmo), &
2077 n_el_f=real(maxocc*nmo,
dp), maxocc=maxocc, &
2078 flexible_electron_count=0.0_dp)
2079 CALL set_mo_set(mo_set(ispin), uniform_occupation=.true., homo=nmo)
2080 ALLOCATE (mo_set(ispin)%mo_coeff)
2082 matrix_struct=mixed_mo_coeff(1, ispin)%matrix_struct, &
2083 name=
"GS_MO_COEFF"//trim(adjustl(
cp_to_string(ispin)))//
"MATRIX")
2084 ALLOCATE (mo_set(ispin)%eigenvalues(nmo))
2085 ALLOCATE (mo_set(ispin)%occupation_numbers(nmo))
2088 IF (force_env%mixed_env%do_mixed_qmmm_cdft) &
2090 CALL cp_abort(__location__, &
2091 "QMMM + wavefunction overlap method not supported.")
2094 CALL cp_subsys_get(subsys_mix, atomic_kind_set=atomic_kind_set, particle_set=particle_set)
2095 cpassert(
ASSOCIATED(mixed_cdft%qs_kind_set))
2096 IF (force_env%para_env%is_source()) &
2098 CALL force_env%para_env%bcast(exist)
2099 CALL force_env%para_env%bcast(file_name)
2101 CALL cp_abort(__location__, &
2102 "User requested to restart the wavefunction from the file named: "// &
2103 trim(file_name)//
". This file does not exist. Please check the existence of"// &
2104 " the file or change properly the value of the keyword WFN_RESTART_FILE_NAME in"// &
2105 " section FORCE_EVAL\MIXED\MIXED_CDFT.")
2107 para_env=force_env%para_env, id_nr=0, multiplicity=mixed_cdft%multiplicity, &
2108 dft_section=mixed_cdft_section, natom_mismatch=natom_mismatch, &
2110 IF (natom_mismatch) &
2111 CALL cp_abort(__location__, &
2112 "Restart wfn file has a wrong number of atoms")
2114 DO ispin = 1, nspins
2115 IF (mixed_cdft%has_unit_metric)
THEN
2118 CALL make_basis_sm(mo_set(ispin)%mo_coeff, ncol_mo(ispin), mixed_matrix_s)
2122 ALLOCATE (coupling_wfn(npermutations))
2123 ALLOCATE (overlaps(2, npermutations, nspins))
2125 DO ispin = 1, nspins
2127 nao = nrow_mo(ispin)
2128 nmo = ncol_mo(ispin)
2130 context=mixed_cdft%blacs_env, para_env=force_env%para_env)
2131 CALL cp_fm_create(matrix=mo_overlap_wfn, matrix_struct=mo_mo_fmstruct, &
2132 name=
"MO_OVERLAP_MATRIX_WFN")
2133 CALL cp_fm_create(matrix=inverse_mat, matrix_struct=mo_mo_fmstruct, &
2134 name=
"INVERSE_MO_OVERLAP_MATRIX_WFN")
2137 matrix_struct=mixed_mo_coeff(1, ispin)%matrix_struct, &
2138 name=
"OVERLAP_MO_COEFF_WFN")
2139 DO ipermutation = 1, npermutations
2143 mo_tmp, nmo, 1.0_dp, 0.0_dp)
2147 mixed_mo_coeff(istate, ispin), &
2148 mo_tmp, 0.0_dp, mo_overlap_wfn)
2149 CALL cp_fm_invert(mo_overlap_wfn, inverse_mat, overlaps(1, ipermutation, ispin), eps_svd=mixed_cdft%eps_svd)
2153 mixed_mo_coeff(jstate, ispin), &
2154 mo_tmp, 0.0_dp, mo_overlap_wfn)
2155 CALL cp_fm_invert(mo_overlap_wfn, inverse_mat, overlaps(2, ipermutation, ispin), eps_svd=mixed_cdft%eps_svd)
2163 DO ipermutation = 1, npermutations
2165 IF (nspins == 2)
THEN
2166 overlaps(1, ipermutation, 1) = abs(overlaps(1, ipermutation, 1)*overlaps(1, ipermutation, 2))
2167 overlaps(2, ipermutation, 1) = abs(overlaps(2, ipermutation, 1)*overlaps(2, ipermutation, 2))
2169 overlaps(1, ipermutation, 1) = overlaps(1, ipermutation, 1)**2
2170 overlaps(2, ipermutation, 1) = overlaps(2, ipermutation, 1)**2
2174 IF (abs(overlaps(1, ipermutation, 1) - overlaps(2, ipermutation, 1)) .LE. 1.0e-14_dp)
THEN
2175 CALL cp_warn(__location__, &
2176 "Coupling between states is singular and set to zero. "// &
2177 "Potential causes: coupling is computed between identical CDFT states or the spin/charge "// &
2178 "density is fully delocalized in the unconstrained ground state.")
2179 coupling_wfn(ipermutation) = 0.0_dp
2181 energy_diff = mixed_cdft%results%energy(jstate) - mixed_cdft%results%energy(istate)
2182 sda = mixed_cdft%results%S(istate, jstate)
2183 coupling_wfn(ipermutation) = abs((overlaps(1, ipermutation, 1)*overlaps(2, ipermutation, 1)/ &
2184 (overlaps(1, ipermutation, 1)**2 - overlaps(2, ipermutation, 1)**2))* &
2185 (energy_diff)/(1.0_dp - sda**2)* &
2186 (1.0_dp - (overlaps(1, ipermutation, 1)**2 + overlaps(2, ipermutation, 1)**2)/ &
2187 (2.0_dp*overlaps(1, ipermutation, 1)*overlaps(2, ipermutation, 1))* &
2191 DEALLOCATE (overlaps)
2193 DEALLOCATE (coupling_wfn)
2194 CALL timestop(handle)
2196 END SUBROUTINE mixed_cdft_wfn_overlap_method
2210 SUBROUTINE mixed_becke_constraint(force_env, calculate_forces)
2212 LOGICAL,
INTENT(IN) :: calculate_forces
2214 CHARACTER(len=*),
PARAMETER :: routinen =
'mixed_becke_constraint'
2217 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: catom
2218 LOGICAL :: in_memory, store_vectors
2219 LOGICAL,
ALLOCATABLE,
DIMENSION(:) :: is_constraint
2220 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: coefficients
2221 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: position_vecs, r12
2222 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :, :) :: pair_dist_vecs
2227 NULLIFY (mixed_env, mixed_cdft)
2228 store_vectors = .true.
2230 CALL timeset(routinen, handle)
2231 mixed_env => force_env%mixed_env
2233 CALL mixed_becke_constraint_init(force_env, mixed_cdft, calculate_forces, &
2234 is_constraint, in_memory, store_vectors, &
2235 r12, position_vecs, pair_dist_vecs, &
2236 coefficients, catom)
2237 CALL mixed_becke_constraint_low(force_env, mixed_cdft, in_memory, &
2238 is_constraint, store_vectors, r12, &
2239 position_vecs, pair_dist_vecs, &
2240 coefficients, catom)
2241 CALL timestop(handle)
2243 END SUBROUTINE mixed_becke_constraint
2262 SUBROUTINE mixed_becke_constraint_init(force_env, mixed_cdft, calculate_forces, &
2263 is_constraint, in_memory, store_vectors, &
2264 R12, position_vecs, pair_dist_vecs, coefficients, &
2268 LOGICAL,
INTENT(IN) :: calculate_forces
2269 LOGICAL,
ALLOCATABLE,
DIMENSION(:),
INTENT(OUT) :: is_constraint
2270 LOGICAL,
INTENT(OUT) :: in_memory
2271 LOGICAL,
INTENT(IN) :: store_vectors
2272 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :), &
2273 INTENT(out) :: r12, position_vecs
2274 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :, :), &
2275 INTENT(out) :: pair_dist_vecs
2276 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:), &
2277 INTENT(OUT) :: coefficients
2278 INTEGER,
ALLOCATABLE,
DIMENSION(:),
INTENT(out) :: catom
2280 CHARACTER(len=*),
PARAMETER :: routinen =
'mixed_becke_constraint_init'
2282 CHARACTER(len=2) :: element_symbol
2283 INTEGER :: atom_a, bounds(2), handle, i, iatom, iex, iforce_eval, ikind, iounit, ithread, j, &
2284 jatom, katom, my_work, my_work_size, natom, nforce_eval, nkind, np(3), npme, nthread, &
2285 numexp, offset_dlb, unit_nr
2286 INTEGER,
DIMENSION(2, 3) :: bo, bo_conf
2287 INTEGER,
DIMENSION(:),
POINTER :: atom_list, cores, stride
2288 LOGICAL :: build, mpi_io
2289 REAL(kind=
dp) :: alpha, chi, coef, ircov, jrcov, ra(3), &
2291 REAL(kind=
dp),
DIMENSION(3) :: cell_v, dist_vec, dr, r, r1, shift
2292 REAL(kind=
dp),
DIMENSION(:),
POINTER :: radii_list
2293 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: pab
2304 TYPE(
qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
2308 NULLIFY (pab, cell, force_env_qs, particle_set, force_env_section, print_section, &
2309 qs_kind_set, particles, subsys_mix, rs_cavity, cavity_env, auxbas_pw_pool, &
2310 atomic_kind_set, radii_list, cdft_control)
2312 nforce_eval =
SIZE(force_env%sub_force_env)
2313 CALL timeset(routinen, handle)
2314 CALL force_env_get(force_env=force_env, force_env_section=force_env_section)
2315 IF (.NOT. force_env%mixed_env%do_mixed_qmmm_cdft)
THEN
2317 subsys=subsys_mix, &
2320 particles=particles, &
2321 particle_set=particle_set)
2323 DO iforce_eval = 1, nforce_eval
2324 IF (.NOT.
ASSOCIATED(force_env%sub_force_env(iforce_eval)%force_env)) cycle
2325 force_env_qs => force_env%sub_force_env(iforce_eval)%force_env
2327 CALL get_qs_env(force_env_qs%qmmm_env%qs_env, &
2328 cp_subsys=subsys_mix, &
2331 particles=particles, &
2332 particle_set=particle_set)
2334 natom =
SIZE(particles%els)
2336 cdft_control => mixed_cdft%cdft_control
2337 cpassert(
ASSOCIATED(cdft_control))
2338 IF (.NOT.
ASSOCIATED(cdft_control%becke_control%cutoffs))
THEN
2339 CALL cp_subsys_get(subsys_mix, atomic_kind_set=atomic_kind_set)
2340 ALLOCATE (cdft_control%becke_control%cutoffs(natom))
2341 SELECT CASE (cdft_control%becke_control%cutoff_type)
2343 cdft_control%becke_control%cutoffs(:) = cdft_control%becke_control%rglobal
2345 IF (.NOT.
SIZE(atomic_kind_set) ==
SIZE(cdft_control%becke_control%cutoffs_tmp)) &
2346 CALL cp_abort(__location__, &
2347 "Size of keyword BECKE_CONSTRAINT\ELEMENT_CUTOFFS does "// &
2348 "not match number of atomic kinds in the input coordinate file.")
2349 DO ikind = 1,
SIZE(atomic_kind_set)
2350 CALL get_atomic_kind(atomic_kind_set(ikind), natom=katom, atom_list=atom_list)
2352 atom_a = atom_list(iatom)
2353 cdft_control%becke_control%cutoffs(atom_a) = cdft_control%becke_control%cutoffs_tmp(ikind)
2356 DEALLOCATE (cdft_control%becke_control%cutoffs_tmp)
2360 IF (cdft_control%becke_control%adjust .AND. &
2361 .NOT.
ASSOCIATED(cdft_control%becke_control%aij))
THEN
2362 ALLOCATE (cdft_control%becke_control%aij(natom, natom))
2365 ALLOCATE (catom(cdft_control%natoms))
2366 IF (cdft_control%save_pot .OR. &
2367 cdft_control%becke_control%cavity_confine .OR. &
2368 cdft_control%becke_control%should_skip .OR. &
2369 mixed_cdft%first_iteration)
THEN
2370 ALLOCATE (is_constraint(natom))
2371 is_constraint = .false.
2373 in_memory = calculate_forces .AND. cdft_control%becke_control%in_memory
2374 IF (in_memory .NEQV. calculate_forces) &
2375 CALL cp_abort(__location__, &
2376 "The flag BECKE_CONSTRAINT\IN_MEMORY must be activated "// &
2377 "for the calculation of mixed CDFT forces")
2378 IF (in_memory .OR. mixed_cdft%first_iteration)
ALLOCATE (coefficients(natom))
2379 DO i = 1, cdft_control%natoms
2380 catom(i) = cdft_control%atoms(i)
2381 IF (cdft_control%save_pot .OR. &
2382 cdft_control%becke_control%cavity_confine .OR. &
2383 cdft_control%becke_control%should_skip .OR. &
2384 mixed_cdft%first_iteration) &
2385 is_constraint(catom(i)) = .true.
2386 IF (in_memory .OR. mixed_cdft%first_iteration) &
2387 coefficients(catom(i)) = cdft_control%group(1)%coeff(i)
2389 CALL pw_env_get(pw_env=mixed_cdft%pw_env, auxbas_pw_pool=auxbas_pw_pool)
2390 bo = auxbas_pw_pool%pw_grid%bounds_local
2391 np = auxbas_pw_pool%pw_grid%npts
2392 dr = auxbas_pw_pool%pw_grid%dr
2393 shift = -real(
modulo(np, 2),
dp)*dr/2.0_dp
2394 IF (store_vectors)
THEN
2395 IF (in_memory)
ALLOCATE (pair_dist_vecs(3, natom, natom))
2396 ALLOCATE (position_vecs(3, natom))
2399 cell_v(i) = cell%hmat(i, i)
2401 ALLOCATE (r12(natom, natom))
2402 DO iatom = 1, natom - 1
2403 DO jatom = iatom + 1, natom
2404 r = particle_set(iatom)%r
2405 r1 = particle_set(jatom)%r
2407 r(i) =
modulo(r(i), cell%hmat(i, i)) - cell%hmat(i, i)/2._dp
2408 r1(i) =
modulo(r1(i), cell%hmat(i, i)) - cell%hmat(i, i)/2._dp
2410 dist_vec = (r - r1) - anint((r - r1)/cell_v)*cell_v
2411 IF (store_vectors)
THEN
2412 position_vecs(:, iatom) = r(:)
2413 IF (iatom == 1 .AND. jatom == natom) position_vecs(:, jatom) = r1(:)
2415 pair_dist_vecs(:, iatom, jatom) = dist_vec(:)
2416 pair_dist_vecs(:, jatom, iatom) = -dist_vec(:)
2419 r12(iatom, jatom) = sqrt(dot_product(dist_vec, dist_vec))
2420 r12(jatom, iatom) = r12(iatom, jatom)
2424 ircov = cdft_control%becke_control%radii(ikind)
2427 jrcov = cdft_control%becke_control%radii(ikind)
2428 IF (ircov .NE. jrcov)
THEN
2430 uij = (chi - 1.0_dp)/(chi + 1.0_dp)
2431 cdft_control%becke_control%aij(iatom, jatom) = uij/(uij**2 - 1.0_dp)
2432 IF (cdft_control%becke_control%aij(iatom, jatom) &
2434 cdft_control%becke_control%aij(iatom, jatom) = 0.5_dp
2435 ELSE IF (cdft_control%becke_control%aij(iatom, jatom) &
2437 cdft_control%becke_control%aij(iatom, jatom) = -0.5_dp
2440 cdft_control%becke_control%aij(iatom, jatom) = 0.0_dp
2442 cdft_control%becke_control%aij(jatom, iatom) = &
2443 -cdft_control%becke_control%aij(iatom, jatom)
2448 IF (mixed_cdft%first_iteration)
THEN
2451 IF (iounit > 0)
THEN
2452 WRITE (iounit,
'(/,T3,A,T66)') &
2453 '-------------------------- Becke atomic parameters ---------------------------'
2454 IF (cdft_control%becke_control%adjust)
THEN
2455 WRITE (iounit,
'(T3,A,A)') &
2456 'Atom Element Coefficient',
' Cutoff (angstrom) CDFT Radius (angstrom)'
2459 element_symbol=element_symbol, &
2462 IF (is_constraint(iatom))
THEN
2463 coef = coefficients(iatom)
2467 WRITE (iounit,
"(i6,T14,A2,T22,F8.3,T44,F8.3,T73,F8.3)") &
2468 iatom, adjustr(element_symbol), coef, &
2473 WRITE (iounit,
'(T3,A,A)') &
2474 'Atom Element Coefficient',
' Cutoff (angstrom)'
2477 element_symbol=element_symbol)
2478 IF (is_constraint(iatom))
THEN
2479 coef = coefficients(iatom)
2483 WRITE (iounit,
"(i6,T14,A2,T22,F8.3,T44,F8.3)") &
2484 iatom, adjustr(element_symbol), coef, &
2488 WRITE (iounit,
'(T3,A)') &
2489 '------------------------------------------------------------------------------'
2492 "MIXED%MIXED_CDFT%PRINT%PROGRAM_RUN_INFO")
2493 mixed_cdft%first_iteration = .false.
2496 IF (cdft_control%becke_control%cavity_confine)
THEN
2497 cpassert(
ASSOCIATED(mixed_cdft%qs_kind_set))
2498 cavity_env => cdft_control%becke_control%cavity_env
2499 qs_kind_set => mixed_cdft%qs_kind_set
2500 CALL cp_subsys_get(subsys_mix, atomic_kind_set=atomic_kind_set)
2501 nkind =
SIZE(qs_kind_set)
2502 IF (.NOT.
ASSOCIATED(cavity_env%kind_shape_fn))
THEN
2503 IF (
ASSOCIATED(cdft_control%becke_control%radii))
THEN
2504 ALLOCATE (radii_list(
SIZE(cdft_control%becke_control%radii)))
2505 DO ikind = 1,
SIZE(cdft_control%becke_control%radii)
2506 IF (cavity_env%use_bohr)
THEN
2507 radii_list(ikind) = cdft_control%becke_control%radii(ikind)
2509 radii_list(ikind) =
cp_unit_from_cp2k(cdft_control%becke_control%radii(ikind),
"angstrom")
2514 radius=cdft_control%becke_control%rcavity, &
2515 radii_list=radii_list)
2516 IF (
ASSOCIATED(radii_list)) &
2517 DEALLOCATE (radii_list)
2520 CALL pw_env_get(pw_env=mixed_cdft%pw_env, auxbas_rs_grid=rs_cavity, &
2521 auxbas_pw_pool=auxbas_pw_pool)
2524 ALLOCATE (pab(1, 1))
2527 DO ikind = 1,
SIZE(atomic_kind_set)
2528 numexp = cavity_env%kind_shape_fn(ikind)%numexp
2529 IF (numexp <= 0) cycle
2530 CALL get_atomic_kind(atomic_kind_set(ikind), natom=katom, atom_list=atom_list)
2531 ALLOCATE (cores(katom))
2533 alpha = cavity_env%kind_shape_fn(ikind)%zet(iex)
2534 coef = cavity_env%kind_shape_fn(ikind)%coef(iex)
2538 IF (rs_cavity%desc%parallel .AND. .NOT. rs_cavity%desc%distributed)
THEN
2540 IF (
modulo(iatom, rs_cavity%desc%group_size) == rs_cavity%desc%my_pos)
THEN
2551 atom_a = atom_list(iatom)
2553 IF (store_vectors)
THEN
2554 ra(:) = position_vecs(:, atom_a) + cell_v(:)/2._dp
2556 ra(:) =
pbc(particle_set(atom_a)%r, cell)
2558 IF (is_constraint(atom_a))
THEN
2560 ra=ra, rb=ra, rp=ra, &
2561 zetp=alpha, eps=mixed_cdft%eps_rho_rspace, &
2562 pab=pab, o1=0, o2=0, &
2563 prefactor=1.0_dp, cutoff=0.0_dp)
2566 (/0.0_dp, 0.0_dp, 0.0_dp/), 1.0_dp, pab, 0, 0, &
2569 use_subpatch=.true., &
2577 CALL auxbas_pw_pool%create_pw(cdft_control%becke_control%cavity)
2578 CALL transfer_rs2pw(rs_cavity, cdft_control%becke_control%cavity)
2579 CALL hfun_zero(cdft_control%becke_control%cavity%array, &
2580 cdft_control%becke_control%eps_cavity, &
2581 just_zero=.false., bounds=bounds, work=my_work)
2582 IF (bounds(2) .LT. bo(2, 3))
THEN
2583 bounds(2) = bounds(2) - 1
2585 bounds(2) = bo(2, 3)
2587 IF (bounds(1) .GT. bo(1, 3))
THEN
2591 bounds(1) = bounds(1) + 1
2593 bounds(1) = bo(1, 3)
2595 IF (bounds(1) > bounds(2))
THEN
2598 my_work_size = (bounds(2) - bounds(1) + 1)
2599 IF (mixed_cdft%is_pencil .OR. mixed_cdft%is_special)
THEN
2600 my_work_size = my_work_size*(bo(2, 2) - bo(1, 2) + 1)
2602 my_work_size = my_work_size*(bo(2, 1) - bo(1, 1) + 1)
2605 cdft_control%becke_control%confine_bounds = bounds
2606 IF (cdft_control%becke_control%print_cavity)
THEN
2607 CALL hfun_zero(cdft_control%becke_control%cavity%array, &
2608 cdft_control%becke_control%eps_cavity, just_zero=.true.)
2610 ALLOCATE (stride(3))
2611 stride = (/2, 2, 2/)
2614 middle_name=
"BECKE_CAVITY", &
2615 extension=
".cube", file_position=
"REWIND", &
2616 log_filename=.false., mpi_io=mpi_io)
2617 IF (force_env%para_env%is_source() .AND. unit_nr .LT. 1) &
2618 CALL cp_abort(__location__, &
2619 "Please turn on PROGRAM_RUN_INFO to print cavity")
2621 unit_nr,
"CAVITY", particles=particles, &
2622 stride=stride, mpi_io=mpi_io)
2628 IF (cdft_control%becke_control%cavity_confine) &
2629 bo_conf(:, 3) = cdft_control%becke_control%confine_bounds
2631 IF (mixed_cdft%dlb) &
2632 CALL mixed_becke_constraint_dlb(force_env, mixed_cdft, my_work, &
2633 my_work_size, natom, bo, bo_conf)
2636 IF (mixed_cdft%dlb)
THEN
2637 IF (mixed_cdft%dlb_control%send_work .AND. .NOT. mixed_cdft%is_special) &
2638 offset_dlb = sum(mixed_cdft%dlb_control%target_list(2, :))
2640 IF (cdft_control%becke_control%cavity_confine)
THEN
2642 IF (mixed_cdft%is_special)
THEN
2643 ALLOCATE (mixed_cdft%sendbuff(
SIZE(mixed_cdft%dest_list)))
2644 DO i = 1,
SIZE(mixed_cdft%dest_list)
2645 ALLOCATE (mixed_cdft%sendbuff(i)%cavity(mixed_cdft%dest_list_bo(1, i):mixed_cdft%dest_list_bo(2, i), &
2646 bo(1, 2):bo(2, 2), bo_conf(1, 3):bo_conf(2, 3)))
2647 mixed_cdft%sendbuff(i)%cavity = cdft_control%becke_control%cavity%array(mixed_cdft%dest_list_bo(1, i): &
2648 mixed_cdft%dest_list_bo(2, i), &
2649 bo(1, 2):bo(2, 2), &
2650 bo_conf(1, 3):bo_conf(2, 3))
2652 ELSE IF (mixed_cdft%is_pencil)
THEN
2653 ALLOCATE (mixed_cdft%cavity(bo(1, 1) + offset_dlb:bo(2, 1), bo(1, 2):bo(2, 2), bo_conf(1, 3):bo_conf(2, 3)))
2654 mixed_cdft%cavity = cdft_control%becke_control%cavity%array(bo(1, 1) + offset_dlb:bo(2, 1), &
2655 bo(1, 2):bo(2, 2), &
2656 bo_conf(1, 3):bo_conf(2, 3))
2658 ALLOCATE (mixed_cdft%cavity(bo(1, 1):bo(2, 1), bo(1, 2) + offset_dlb:bo(2, 2), bo_conf(1, 3):bo_conf(2, 3)))
2659 mixed_cdft%cavity = cdft_control%becke_control%cavity%array(bo(1, 1):bo(2, 1), &
2660 bo(1, 2) + offset_dlb:bo(2, 2), &
2661 bo_conf(1, 3):bo_conf(2, 3))
2663 CALL auxbas_pw_pool%give_back_pw(cdft_control%becke_control%cavity)
2665 IF (mixed_cdft%is_special)
THEN
2666 DO i = 1,
SIZE(mixed_cdft%dest_list)
2667 ALLOCATE (mixed_cdft%sendbuff(i)%weight(mixed_cdft%dest_list_bo(1, i):mixed_cdft%dest_list_bo(2, i), &
2668 bo(1, 2):bo(2, 2), bo_conf(1, 3):bo_conf(2, 3)))
2669 mixed_cdft%sendbuff(i)%weight = 0.0_dp
2671 ELSE IF (mixed_cdft%is_pencil)
THEN
2672 ALLOCATE (mixed_cdft%weight(bo(1, 1) + offset_dlb:bo(2, 1), bo(1, 2):bo(2, 2), bo_conf(1, 3):bo_conf(2, 3)))
2673 mixed_cdft%weight = 0.0_dp
2675 ALLOCATE (mixed_cdft%weight(bo(1, 1):bo(2, 1), bo(1, 2) + offset_dlb:bo(2, 2), bo_conf(1, 3):bo_conf(2, 3)))
2676 mixed_cdft%weight = 0.0_dp
2679 IF (mixed_cdft%is_special)
THEN
2680 DO i = 1,
SIZE(mixed_cdft%dest_list)
2681 ALLOCATE (mixed_cdft%sendbuff(i)%gradients(3*natom, mixed_cdft%dest_list_bo(1, i): &
2682 mixed_cdft%dest_list_bo(2, i), &
2683 bo(1, 2):bo(2, 2), &
2684 bo_conf(1, 3):bo_conf(2, 3)))
2685 mixed_cdft%sendbuff(i)%gradients = 0.0_dp
2687 ELSE IF (mixed_cdft%is_pencil)
THEN
2688 ALLOCATE (cdft_control%group(1)%gradients(3*natom, bo(1, 1) + offset_dlb:bo(2, 1), &
2689 bo(1, 2):bo(2, 2), &
2690 bo_conf(1, 3):bo_conf(2, 3)))
2691 cdft_control%group(1)%gradients = 0.0_dp
2693 ALLOCATE (cdft_control%group(1)%gradients(3*natom, bo(1, 1):bo(2, 1), &
2694 bo(1, 2) + offset_dlb:bo(2, 2), &
2695 bo_conf(1, 3):bo_conf(2, 3)))
2696 cdft_control%group(1)%gradients = 0.0_dp
2700 CALL timestop(handle)
2702 END SUBROUTINE mixed_becke_constraint_init
2717 SUBROUTINE mixed_becke_constraint_dlb(force_env, mixed_cdft, my_work, &
2718 my_work_size, natom, bo, bo_conf)
2721 INTEGER,
INTENT(IN) :: my_work, my_work_size, natom
2722 INTEGER,
DIMENSION(2, 3) :: bo, bo_conf
2724 CHARACTER(len=*),
PARAMETER :: routinen =
'mixed_becke_constraint_dlb'
2725 INTEGER,
PARAMETER :: should_deallocate = 7000, &
2726 uninitialized = -7000
2728 INTEGER :: actually_sent, exhausted_work, handle, i, ind, iounit, ispecial, j, max_targets, &
2729 more_work, my_pos, my_special_work, my_target, no_overloaded, no_underloaded, nsend, &
2730 nsend_limit, nsend_max, offset, offset_proc, offset_special, send_total, tags(2)
2731 INTEGER,
DIMENSION(:),
POINTER :: buffsize, cumulative_work, expected_work, load_imbalance, &
2732 nrecv, nsend_proc, sendbuffer, should_warn, tmp, work_index, work_size
2733 INTEGER,
DIMENSION(:, :),
POINTER :: targets, tmp_bo
2734 LOGICAL :: consistent
2735 LOGICAL,
DIMENSION(:),
POINTER :: mask_recv, mask_send, touched
2736 REAL(kind=
dp) :: average_work, load_scale, &
2737 very_overloaded, work_factor
2738 REAL(kind=
dp),
DIMENSION(:, :, :),
POINTER :: cavity
2746 LOGICAL,
POINTER,
DIMENSION(:) :: bv
2747 INTEGER,
POINTER,
DIMENSION(:) :: iv
2749 TYPE(buffers),
POINTER,
DIMENSION(:) :: recvbuffer, sbuff
2750 CHARACTER(len=2) :: dummy
2753 CALL timeset(routinen, handle)
2754 mixed_cdft%dlb_control%recv_work = .false.
2755 mixed_cdft%dlb_control%send_work = .false.
2756 NULLIFY (expected_work, work_index, load_imbalance, work_size, &
2757 cumulative_work, sendbuffer, buffsize, req_recv, req_total, &
2758 tmp, nrecv, nsend_proc, targets, tmp_bo, touched, &
2759 mask_recv, mask_send, cavity, recvbuffer, sbuff, force_env_section, &
2760 print_section, cdft_control)
2761 CALL force_env_get(force_env=force_env, force_env_section=force_env_section)
2764 cdft_control => mixed_cdft%cdft_control
2769 load_scale = mixed_cdft%dlb_control%load_scale
2770 very_overloaded = mixed_cdft%dlb_control%very_overloaded
2771 more_work = mixed_cdft%dlb_control%more_work
2773 work_factor = 0.8_dp
2775 IF (mixed_cdft%is_special)
THEN
2776 DEALLOCATE (mixed_cdft%dest_list, mixed_cdft%dest_list_bo, &
2777 mixed_cdft%source_list, mixed_cdft%source_list_bo)
2778 ALLOCATE (mixed_cdft%dest_list(
SIZE(mixed_cdft%dest_list_save)), &
2779 mixed_cdft%dest_list_bo(
SIZE(mixed_cdft%dest_bo_save, 1),
SIZE(mixed_cdft%dest_bo_save, 2)), &
2780 mixed_cdft%source_list(
SIZE(mixed_cdft%source_list_save)), &
2781 mixed_cdft%source_list_bo(
SIZE(mixed_cdft%source_bo_save, 1),
SIZE(mixed_cdft%source_bo_save, 2)))
2782 mixed_cdft%dest_list = mixed_cdft%dest_list_save
2783 mixed_cdft%source_list = mixed_cdft%source_list_save
2784 mixed_cdft%dest_list_bo = mixed_cdft%dest_bo_save
2785 mixed_cdft%source_list_bo = mixed_cdft%source_bo_save
2787 ALLOCATE (mixed_cdft%dlb_control%expected_work(force_env%para_env%num_pe), &
2788 expected_work(force_env%para_env%num_pe), &
2789 work_size(force_env%para_env%num_pe))
2790 IF (debug_this_module)
THEN
2791 ALLOCATE (should_warn(force_env%para_env%num_pe))
2795 expected_work(force_env%para_env%mepos + 1) = my_work
2797 work_size(force_env%para_env%mepos + 1) = my_work_size
2798 IF (
ASSOCIATED(mixed_cdft%dlb_control%prediction_error))
THEN
2799 IF (mixed_cdft%is_pencil .OR. mixed_cdft%is_special)
THEN
2800 work_size(force_env%para_env%mepos + 1) = work_size(force_env%para_env%mepos + 1) - &
2801 nint(real(mixed_cdft%dlb_control% &
2802 prediction_error(force_env%para_env%mepos + 1),
dp)/ &
2803 REAL(bo(2, 1) - bo(1, 1) + 1,
dp))
2805 work_size(force_env%para_env%mepos + 1) = work_size(force_env%para_env%mepos + 1) - &
2806 nint(real(mixed_cdft%dlb_control% &
2807 prediction_error(force_env%para_env%mepos + 1),
dp)/ &
2808 REAL(bo(2, 2) - bo(1, 2) + 1,
dp))
2811 CALL force_env%para_env%sum(expected_work)
2812 CALL force_env%para_env%sum(work_size)
2814 mixed_cdft%dlb_control%expected_work = expected_work
2816 IF (
ASSOCIATED(mixed_cdft%dlb_control%prediction_error)) &
2817 expected_work = expected_work - mixed_cdft%dlb_control%prediction_error
2819 average_work = real(sum(expected_work),
dp)/real(force_env%para_env%num_pe,
dp)
2820 ALLOCATE (work_index(force_env%para_env%num_pe), &
2821 load_imbalance(force_env%para_env%num_pe), &
2822 targets(2, force_env%para_env%num_pe))
2823 load_imbalance = expected_work - nint(average_work)
2828 DO i = 1, force_env%para_env%num_pe
2829 IF (load_imbalance(i) .GT. 0)
THEN
2830 no_overloaded = no_overloaded + 1
2832 IF (expected_work(i) .GT. nint(very_overloaded*average_work))
THEN
2833 load_imbalance(i) = (ceiling(real(load_imbalance(i),
dp)/real(work_size(i),
dp)) + more_work)*work_size(i)
2835 load_imbalance(i) = ceiling(real(load_imbalance(i),
dp)/real(work_size(i),
dp))*work_size(i)
2840 load_imbalance(i) = nint(load_imbalance(i)*load_scale)
2841 no_underloaded = no_underloaded + 1
2844 CALL sort(expected_work, force_env%para_env%num_pe, indices=work_index)
2847 IF (load_imbalance(force_env%para_env%mepos + 1) > 0)
THEN
2849 mixed_cdft%dlb_control%send_work = .true.
2851 ALLOCATE (cumulative_work(force_env%para_env%num_pe))
2853 DO i = force_env%para_env%num_pe, force_env%para_env%num_pe - no_overloaded + 1, -1
2854 IF (work_index(i) == force_env%para_env%mepos + 1)
THEN
2857 offset = offset + load_imbalance(work_index(i))
2858 IF (i == force_env%para_env%num_pe)
THEN
2859 cumulative_work(i) = load_imbalance(work_index(i))
2861 cumulative_work(i) = cumulative_work(i + 1) + load_imbalance(work_index(i))
2866 j = force_env%para_env%num_pe
2867 nsend_max = load_imbalance(work_index(j))/work_size(work_index(j))
2870 DO i = 1, no_underloaded
2871 IF (my_pos == force_env%para_env%num_pe)
EXIT
2872 nsend = -load_imbalance(work_index(i))/work_size(work_index(j))
2873 IF (nsend .LT. 1) nsend = 1
2874 nsend_max = nsend_max - nsend
2875 IF (nsend_max .LT. 0) nsend = nsend + nsend_max
2876 exhausted_work = exhausted_work + nsend*work_size(work_index(j))
2877 offset = offset - nsend*work_size(work_index(j))
2878 IF (offset .LT. 0)
EXIT
2879 IF (exhausted_work .EQ. cumulative_work(j))
THEN
2881 nsend_max = load_imbalance(work_index(j))/work_size(work_index(j))
2886 IF (i .GT. no_underloaded)
THEN
2890 DEALLOCATE (cumulative_work)
2892 nsend_max = load_imbalance(force_env%para_env%mepos + 1)/work_size(force_env%para_env%mepos + 1)
2894 IF (mixed_cdft%is_pencil .OR. mixed_cdft%is_special)
THEN
2895 nsend_limit = bo(2, 1) - bo(1, 1) + 1
2897 nsend_limit = bo(2, 2) - bo(1, 2) + 1
2899 IF (.NOT. mixed_cdft%is_special)
THEN
2900 ALLOCATE (mixed_cdft%dlb_control%target_list(3, max_targets))
2902 ALLOCATE (mixed_cdft%dlb_control%target_list(3 + 2*
SIZE(mixed_cdft%dest_list), max_targets))
2903 ALLOCATE (touched(
SIZE(mixed_cdft%dest_list)))
2906 mixed_cdft%dlb_control%target_list = uninitialized
2910 targets(1, my_pos) = my_target
2914 nsend = -load_imbalance(work_index(my_target))/work_size(force_env%para_env%mepos + 1)
2915 IF (nsend .LT. 1) nsend = 1
2917 IF (nsend .GT. nint(work_factor*nsend_limit - send_total))
THEN
2918 nsend = nint(work_factor*nsend_limit - send_total)
2919 IF (debug_this_module) &
2920 should_warn(force_env%para_env%mepos + 1) = 1
2922 mixed_cdft%dlb_control%target_list(1, i) = work_index(my_target) - 1
2923 IF (mixed_cdft%is_special)
THEN
2924 mixed_cdft%dlb_control%target_list(2, i) = 0
2925 actually_sent = nsend
2926 DO j = ispecial,
SIZE(mixed_cdft%dest_list)
2927 mixed_cdft%dlb_control%target_list(2, i) = mixed_cdft%dlb_control%target_list(2, i) + 1
2929 IF (nsend .LT. mixed_cdft%dest_list_bo(2, j) - mixed_cdft%dest_list_bo(1, j) + 1)
THEN
2930 mixed_cdft%dlb_control%target_list(3 + 2*j - 1, i) = mixed_cdft%dest_list_bo(1, j)
2931 mixed_cdft%dlb_control%target_list(3 + 2*j, i) = mixed_cdft%dest_list_bo(1, j) + nsend - 1
2932 mixed_cdft%dest_list_bo(1, j) = mixed_cdft%dest_list_bo(1, j) + nsend
2936 mixed_cdft%dlb_control%target_list(3 + 2*j - 1, i) = mixed_cdft%dest_list_bo(1, j)
2937 mixed_cdft%dlb_control%target_list(3 + 2*j, i) = mixed_cdft%dest_list_bo(2, j)
2938 nsend = nsend - (mixed_cdft%dest_list_bo(2, j) - mixed_cdft%dest_list_bo(1, j) + 1)
2939 mixed_cdft%dest_list_bo(1:2, j) = should_deallocate
2941 IF (nsend .LE. 0)
EXIT
2943 IF (mixed_cdft%dest_list_bo(1, ispecial) .EQ. should_deallocate) ispecial = j + 1
2944 actually_sent = actually_sent - nsend
2945 nsend_max = nsend_max - actually_sent
2946 send_total = send_total + actually_sent
2948 mixed_cdft%dlb_control%target_list(2, i) = nsend
2949 nsend_max = nsend_max - nsend
2950 send_total = send_total + nsend
2952 IF (nsend_max .LT. 0) nsend_max = 0
2953 IF (nsend_max .EQ. 0)
EXIT
2954 IF (my_target /= no_underloaded)
THEN
2955 my_target = my_target + 1
2958 mixed_cdft%dlb_control%target_list(2, i) = mixed_cdft%dlb_control%target_list(2, i) + nsend_max
2963 IF (i .GT. max_targets) &
2964 CALL cp_abort(__location__, &
2965 "Load balancing error: increase max_targets")
2967 IF (.NOT. mixed_cdft%is_special)
THEN
2968 CALL reallocate(mixed_cdft%dlb_control%target_list, 1, 3, 1, i)
2970 CALL reallocate(mixed_cdft%dlb_control%target_list, 1, 3 + 2*
SIZE(mixed_cdft%dest_list), 1, i)
2972 targets(2, my_pos) = my_target
2974 IF (.NOT. mixed_cdft%is_special)
THEN
2975 IF (send_total .GT. nint(work_factor*nsend_limit)) send_total = nint(work_factor*nsend_limit) - 1
2976 nsend = nint(real(send_total,
dp)/real(
SIZE(mixed_cdft%dlb_control%target_list, 2),
dp))
2977 mixed_cdft%dlb_control%target_list(2, :) = nsend
2980 DO i = 1, no_underloaded
2981 IF (work_index(i) == force_env%para_env%mepos + 1)
EXIT
2985 CALL force_env%para_env%sum(targets)
2986 IF (debug_this_module)
THEN
2987 CALL force_env%para_env%sum(should_warn)
2988 IF (any(should_warn == 1)) &
2989 CALL cp_warn(__location__, &
2990 "MIXED_CDFT DLB: Attempted to redistribute more array"// &
2991 " slices than actually available. Leaving a fraction of the total"// &
2992 " slices on the overloaded processor. Perhaps you have set LOAD_SCALE too high?")
2993 DEALLOCATE (should_warn)
2996 IF (force_env%para_env%is_source())
THEN
2998 DO i = force_env%para_env%num_pe - 1, force_env%para_env%num_pe - no_overloaded + 1, -1
2999 IF (targets(1, i) .GT. no_underloaded) consistent = .false.
3000 IF (targets(1, i) .GT. targets(2, i + 1))
THEN
3003 consistent = .false.
3006 IF (.NOT. consistent)
THEN
3007 IF (debug_this_module .AND. iounit > 0)
THEN
3008 DO i = force_env%para_env%num_pe - 1, force_env%para_env%num_pe - no_overloaded + 1, -1
3009 WRITE (iounit,
'(A,I8,I8,I8,I8,I8)') &
3010 'load balancing info', load_imbalance(i), work_index(i), &
3011 work_size(i), targets(1, i), targets(2, i)
3014 CALL cp_abort(__location__, &
3015 "Load balancing error: too much data to redistribute."// &
3016 " Increase LOAD_SCALE or change the number of processors."// &
3017 " If the confinement cavity occupies a large volume relative"// &
3018 " to the total system volume, it might be worth disabling DLB.")
3022 IF (my_pos .LE. no_underloaded)
THEN
3023 DO i = force_env%para_env%num_pe, force_env%para_env%num_pe - no_overloaded + 1, -1
3024 IF (targets(1, i) .LE. my_pos .AND. targets(2, i) .GE. my_pos)
THEN
3025 mixed_cdft%dlb_control%recv_work = .true.
3026 mixed_cdft%dlb_control%my_source = work_index(i) - 1
3030 IF (mixed_cdft%dlb_control%recv_work)
THEN
3031 IF (.NOT. mixed_cdft%is_special)
THEN
3032 ALLOCATE (mixed_cdft%dlb_control%bo(12))
3033 CALL force_env%para_env%irecv(msgout=mixed_cdft%dlb_control%bo, source=mixed_cdft%dlb_control%my_source, &
3036 mixed_cdft%dlb_control%my_dest_repl = (/mixed_cdft%dlb_control%bo(11), mixed_cdft%dlb_control%bo(12)/)
3037 mixed_cdft%dlb_control%dest_tags_repl = (/mixed_cdft%dlb_control%bo(9), mixed_cdft%dlb_control%bo(10)/)
3038 ALLOCATE (mixed_cdft%dlb_control%cavity(mixed_cdft%dlb_control%bo(1):mixed_cdft%dlb_control%bo(2), &
3039 mixed_cdft%dlb_control%bo(3):mixed_cdft%dlb_control%bo(4), &
3040 mixed_cdft%dlb_control%bo(7):mixed_cdft%dlb_control%bo(8)))
3041 ALLOCATE (mixed_cdft%dlb_control%weight(mixed_cdft%dlb_control%bo(1):mixed_cdft%dlb_control%bo(2), &
3042 mixed_cdft%dlb_control%bo(3):mixed_cdft%dlb_control%bo(4), &
3043 mixed_cdft%dlb_control%bo(7):mixed_cdft%dlb_control%bo(8)))
3044 ALLOCATE (mixed_cdft%dlb_control%gradients(3*natom, &
3045 mixed_cdft%dlb_control%bo(1):mixed_cdft%dlb_control%bo(2), &
3046 mixed_cdft%dlb_control%bo(3):mixed_cdft%dlb_control%bo(4), &
3047 mixed_cdft%dlb_control%bo(7):mixed_cdft%dlb_control%bo(8)))
3048 mixed_cdft%dlb_control%gradients = 0.0_dp
3049 mixed_cdft%dlb_control%weight = 0.0_dp
3050 CALL force_env%para_env%irecv(msgout=mixed_cdft%dlb_control%cavity, source=mixed_cdft%dlb_control%my_source, &
3053 DEALLOCATE (mixed_cdft%dlb_control%bo)
3055 ALLOCATE (buffsize(1))
3056 CALL force_env%para_env%irecv(msgout=buffsize, source=mixed_cdft%dlb_control%my_source, &
3059 ALLOCATE (mixed_cdft%dlb_control%bo(12*buffsize(1)))
3060 CALL force_env%para_env%irecv(msgout=mixed_cdft%dlb_control%bo, source=mixed_cdft%dlb_control%my_source, &
3062 ALLOCATE (mixed_cdft%dlb_control%sendbuff(buffsize(1)))
3063 ALLOCATE (req_recv(buffsize(1)))
3064 DEALLOCATE (buffsize)
3066 DO j = 1,
SIZE(mixed_cdft%dlb_control%sendbuff)
3067 ALLOCATE (mixed_cdft%dlb_control%sendbuff(j)%cavity(mixed_cdft%dlb_control%bo(12*(j - 1) + 1): &
3068 mixed_cdft%dlb_control%bo(12*(j - 1) + 2), &
3069 mixed_cdft%dlb_control%bo(12*(j - 1) + 3): &
3070 mixed_cdft%dlb_control%bo(12*(j - 1) + 4), &
3071 mixed_cdft%dlb_control%bo(12*(j - 1) + 7): &
3072 mixed_cdft%dlb_control%bo(12*(j - 1) + 8)))
3073 CALL force_env%para_env%irecv(msgout=mixed_cdft%dlb_control%sendbuff(j)%cavity, &
3074 source=mixed_cdft%dlb_control%my_source, &
3075 request=req_recv(j))
3076 ALLOCATE (mixed_cdft%dlb_control%sendbuff(j)%weight(mixed_cdft%dlb_control%bo(12*(j - 1) + 1): &
3077 mixed_cdft%dlb_control%bo(12*(j - 1) + 2), &
3078 mixed_cdft%dlb_control%bo(12*(j - 1) + 3): &
3079 mixed_cdft%dlb_control%bo(12*(j - 1) + 4), &
3080 mixed_cdft%dlb_control%bo(12*(j - 1) + 7): &
3081 mixed_cdft%dlb_control%bo(12*(j - 1) + 8)))
3082 ALLOCATE (mixed_cdft%dlb_control%sendbuff(j)%gradients(3*natom, &
3083 mixed_cdft%dlb_control%bo(12*(j - 1) + 1): &
3084 mixed_cdft%dlb_control%bo(12*(j - 1) + 2), &
3085 mixed_cdft%dlb_control%bo(12*(j - 1) + 3): &
3086 mixed_cdft%dlb_control%bo(12*(j - 1) + 4), &
3087 mixed_cdft%dlb_control%bo(12*(j - 1) + 7): &
3088 mixed_cdft%dlb_control%bo(12*(j - 1) + 8)))
3089 mixed_cdft%dlb_control%sendbuff(j)%weight = 0.0_dp
3090 mixed_cdft%dlb_control%sendbuff(j)%gradients = 0.0_dp
3091 mixed_cdft%dlb_control%sendbuff(j)%tag = (/mixed_cdft%dlb_control%bo(12*(j - 1) + 9), &
3092 mixed_cdft%dlb_control%bo(12*(j - 1) + 10)/)
3093 mixed_cdft%dlb_control%sendbuff(j)%rank = (/mixed_cdft%dlb_control%bo(12*(j - 1) + 11), &
3094 mixed_cdft%dlb_control%bo(12*(j - 1) + 12)/)
3097 DEALLOCATE (req_recv)
3101 IF (.NOT. mixed_cdft%is_special)
THEN
3103 ALLOCATE (sendbuffer(12))
3105 DO i = 1,
SIZE(mixed_cdft%dlb_control%target_list, 2)
3106 tags = (/(i - 1)*3 + 1 + force_env%para_env%mepos*6*max_targets, &
3107 (i - 1)*3 + 1 + 3*max_targets + force_env%para_env%mepos*6*max_targets/)
3108 mixed_cdft%dlb_control%target_list(3, i) = tags(1)
3109 IF (mixed_cdft%is_pencil)
THEN
3110 sendbuffer = (/bo_conf(1, 1) + offset, &
3111 bo_conf(1, 1) + offset + (mixed_cdft%dlb_control%target_list(2, i) - 1), &
3112 bo_conf(1, 2), bo_conf(2, 2), bo(1, 3), bo(2, 3), bo_conf(1, 3), bo_conf(2, 3), &
3113 tags(1), tags(2), mixed_cdft%dest_list(1), mixed_cdft%dest_list(2)/)
3115 sendbuffer = (/bo_conf(1, 1), bo_conf(2, 1), &
3116 bo_conf(1, 2) + offset, &
3117 bo_conf(1, 2) + offset + (mixed_cdft%dlb_control%target_list(2, i) - 1), &
3118 bo(1, 3), bo(2, 3), bo_conf(1, 3), bo_conf(2, 3), tags(1), tags(2), &
3119 mixed_cdft%dest_list(1), mixed_cdft%dest_list(2)/)
3121 send_total = send_total + mixed_cdft%dlb_control%target_list(2, i) - 1
3122 CALL force_env%para_env%isend(msgin=sendbuffer, dest=mixed_cdft%dlb_control%target_list(1, i), &
3125 IF (mixed_cdft%is_pencil)
THEN
3126 ALLOCATE (cavity(bo_conf(1, 1) + offset: &
3127 bo_conf(1, 1) + offset + (mixed_cdft%dlb_control%target_list(2, i) - 1), &
3128 bo_conf(1, 2):bo_conf(2, 2), bo_conf(1, 3):bo_conf(2, 3)))
3129 cavity = cdft_control%becke_control%cavity%array(bo_conf(1, 1) + offset: &
3130 bo_conf(1, 1) + offset + &
3131 (mixed_cdft%dlb_control%target_list(2, i) - 1), &
3132 bo_conf(1, 2):bo_conf(2, 2), &
3133 bo_conf(1, 3):bo_conf(2, 3))
3135 ALLOCATE (cavity(bo_conf(1, 1):bo_conf(2, 1), &
3136 bo_conf(1, 2) + offset: &
3137 bo_conf(1, 2) + offset + (mixed_cdft%dlb_control%target_list(2, i) - 1), &
3138 bo_conf(1, 3):bo_conf(2, 3)))
3139 cavity = cdft_control%becke_control%cavity%array(bo_conf(1, 1):bo_conf(2, 1), &
3140 bo_conf(1, 2) + offset: &
3141 bo_conf(1, 2) + offset + &
3142 (mixed_cdft%dlb_control%target_list(2, i) - 1), &
3143 bo_conf(1, 3):bo_conf(2, 3))
3145 CALL force_env%para_env%isend(msgin=cavity, &
3146 dest=mixed_cdft%dlb_control%target_list(1, i), &
3149 offset = offset + mixed_cdft%dlb_control%target_list(2, i)
3152 IF (mixed_cdft%is_pencil)
THEN
3153 mixed_cdft%dlb_control%distributed(1) = bo_conf(1, 1)
3154 mixed_cdft%dlb_control%distributed(2) = bo_conf(1, 1) + offset - 1
3156 mixed_cdft%dlb_control%distributed(1) = bo_conf(1, 2)
3157 mixed_cdft%dlb_control%distributed(2) = bo_conf(1, 2) + offset - 1
3159 DEALLOCATE (sendbuffer)
3161 ALLOCATE (buffsize(1))
3162 DO i = 1,
SIZE(mixed_cdft%dlb_control%target_list, 2)
3163 buffsize = mixed_cdft%dlb_control%target_list(2, i)
3165 tags = (/(i - 1)*3 + 1 + force_env%para_env%mepos*6*max_targets, &
3166 (i - 1)*3 + 1 + 3*max_targets + force_env%para_env%mepos*6*max_targets/)
3167 DO j = 4,
SIZE(mixed_cdft%dlb_control%target_list, 1)
3168 IF (mixed_cdft%dlb_control%target_list(j, i) .GT. uninitialized)
EXIT
3171 offset_proc = j - 4 - (j - 4)/2
3172 CALL force_env%para_env%isend(msgin=buffsize, &
3173 dest=mixed_cdft%dlb_control%target_list(1, i), &
3176 ALLOCATE (sendbuffer(12*buffsize(1)))
3177 DO j = 1, buffsize(1)
3178 sendbuffer(12*(j - 1) + 1:12*(j - 1) + 12) = (/mixed_cdft%dlb_control%target_list(offset_special + 2*(j - 1), i), &
3179 mixed_cdft%dlb_control%target_list(offset_special + 2*j - 1, i), &
3180 bo_conf(1, 2), bo_conf(2, 2), bo(1, 3), bo(2, 3), &
3181 bo_conf(1, 3), bo_conf(2, 3), tags(1), tags(2), &
3182 mixed_cdft%dest_list(j + offset_proc), &
3183 mixed_cdft%dest_list(j + offset_proc) + force_env%para_env%num_pe/2/)
3185 CALL force_env%para_env%isend(msgin=sendbuffer, &
3186 dest=mixed_cdft%dlb_control%target_list(1, i), &
3189 DEALLOCATE (sendbuffer)
3190 DO j = 1, buffsize(1)
3191 ALLOCATE (cavity(mixed_cdft%dlb_control%target_list(offset_special + 2*(j - 1), i): &
3192 mixed_cdft%dlb_control%target_list(offset_special + 2*j - 1, i), &
3193 bo_conf(1, 2):bo_conf(2, 2), bo_conf(1, 3):bo_conf(2, 3)))
3194 cavity = cdft_control%becke_control%cavity%array(lbound(cavity, 1):ubound(cavity, 1), &
3195 bo_conf(1, 2):bo_conf(2, 2), &
3196 bo_conf(1, 3):bo_conf(2, 3))
3197 CALL force_env%para_env%isend(msgin=cavity, &
3198 dest=mixed_cdft%dlb_control%target_list(1, i), &
3204 DEALLOCATE (buffsize)
3207 DEALLOCATE (expected_work, work_size, load_imbalance, work_index, targets)
3211 IF (mixed_cdft%is_special)
THEN
3213 ALLOCATE (mask_send(
SIZE(mixed_cdft%dest_list)), mask_recv(
SIZE(mixed_cdft%source_list)))
3214 ALLOCATE (nsend_proc(
SIZE(mixed_cdft%dest_list)), nrecv(
SIZE(mixed_cdft%source_list)))
3222 ALLOCATE (recvbuffer(
SIZE(mixed_cdft%source_list)), sbuff(
SIZE(mixed_cdft%dest_list)))
3223 ALLOCATE (req_total(my_special_work*
SIZE(mixed_cdft%source_list) + (my_special_work**2)*
SIZE(mixed_cdft%dest_list)))
3224 ALLOCATE (mixed_cdft%dlb_control%recv_work_repl(
SIZE(mixed_cdft%source_list)))
3225 DO i = 1,
SIZE(mixed_cdft%source_list)
3226 NULLIFY (recvbuffer(i)%bv, recvbuffer(i)%iv)
3227 ALLOCATE (recvbuffer(i)%bv(1), recvbuffer(i)%iv(3))
3228 CALL force_env%para_env%irecv(msgout=recvbuffer(i)%bv, &
3229 source=mixed_cdft%source_list(i), &
3230 request=req_total(i), tag=1)
3231 IF (mixed_cdft%is_special) &
3232 CALL force_env%para_env%irecv(msgout=recvbuffer(i)%iv, &
3233 source=mixed_cdft%source_list(i), &
3234 request=req_total(i +
SIZE(mixed_cdft%source_list)), &
3237 DO i = 1, my_special_work
3238 DO j = 1,
SIZE(mixed_cdft%dest_list)
3240 NULLIFY (sbuff(j)%iv, sbuff(j)%bv)
3241 ALLOCATE (sbuff(j)%bv(1))
3242 sbuff(j)%bv = mixed_cdft%dlb_control%send_work
3243 IF (mixed_cdft%is_special)
THEN
3244 ALLOCATE (sbuff(j)%iv(3))
3245 sbuff(j)%iv(1:2) = mixed_cdft%dest_list_bo(1:2, j)
3247 IF (sbuff(j)%iv(1) .EQ. should_deallocate) mask_send(j) = .true.
3248 IF (mixed_cdft%dlb_control%send_work)
THEN
3249 sbuff(j)%bv = touched(j)
3250 IF (touched(j))
THEN
3252 DO ispecial = 1,
SIZE(mixed_cdft%dlb_control%target_list, 2)
3253 IF (mixed_cdft%dlb_control%target_list(4 + 2*(j - 1), ispecial) .NE. uninitialized) &
3256 sbuff(j)%iv(3) = nsend
3257 nsend_proc(j) = nsend
3262 ind = j + (i - 1)*
SIZE(mixed_cdft%dest_list) + my_special_work*
SIZE(mixed_cdft%source_list)
3263 CALL force_env%para_env%isend(msgin=sbuff(j)%bv, &
3264 dest=mixed_cdft%dest_list(j) + (i - 1)*force_env%para_env%num_pe/2, &
3265 request=req_total(ind), tag=1)
3266 IF (mixed_cdft%is_special) &
3267 CALL force_env%para_env%isend(msgin=sbuff(j)%iv, &
3268 dest=mixed_cdft%dest_list(j) + (i - 1)*force_env%para_env%num_pe/2, &
3269 request=req_total(ind + 2*
SIZE(mixed_cdft%dest_list)), tag=2)
3273 DEALLOCATE (req_total)
3274 DO i = 1,
SIZE(mixed_cdft%source_list)
3275 mixed_cdft%dlb_control%recv_work_repl(i) = recvbuffer(i)%bv(1)
3276 IF (mixed_cdft%is_special .AND. mixed_cdft%dlb_control%recv_work_repl(i))
THEN
3277 mixed_cdft%source_list_bo(1:2, i) = recvbuffer(i)%iv(1:2)
3278 nrecv(i) = recvbuffer(i)%iv(3)
3279 IF (recvbuffer(i)%iv(1) .EQ. should_deallocate) mask_recv(i) = .true.
3281 DEALLOCATE (recvbuffer(i)%bv)
3282 IF (
ASSOCIATED(recvbuffer(i)%iv))
DEALLOCATE (recvbuffer(i)%iv)
3284 DO j = 1,
SIZE(mixed_cdft%dest_list)
3285 DEALLOCATE (sbuff(j)%bv)
3286 IF (
ASSOCIATED(sbuff(j)%iv))
DEALLOCATE (sbuff(j)%iv)
3288 DEALLOCATE (recvbuffer)
3291 IF (debug_this_module)
THEN
3292 WRITE (dummy, *) mixed_cdft%is_special
3295 IF (.NOT. mixed_cdft%is_special)
THEN
3296 IF (mixed_cdft%dlb_control%send_work)
THEN
3297 ALLOCATE (req_total(count(mixed_cdft%dlb_control%recv_work_repl) + 2))
3298 ALLOCATE (sendbuffer(6))
3299 IF (mixed_cdft%is_pencil)
THEN
3300 sendbuffer = (/
SIZE(mixed_cdft%dlb_control%target_list, 2), bo_conf(1, 3), bo_conf(2, 3), &
3301 bo_conf(1, 1), bo_conf(1, 2), bo_conf(2, 2)/)
3303 sendbuffer = (/
SIZE(mixed_cdft%dlb_control%target_list, 2), bo_conf(1, 3), bo_conf(2, 3), &
3304 bo_conf(1, 2), bo_conf(1, 1), bo_conf(2, 1)/)
3306 ELSE IF (any(mixed_cdft%dlb_control%recv_work_repl))
THEN
3307 ALLOCATE (req_total(count(mixed_cdft%dlb_control%recv_work_repl)))
3309 IF (any(mixed_cdft%dlb_control%recv_work_repl))
THEN
3310 ALLOCATE (mixed_cdft%dlb_control%recv_info(2))
3311 NULLIFY (mixed_cdft%dlb_control%recv_info(1)%target_list, mixed_cdft%dlb_control%recv_info(2)%target_list)
3312 ALLOCATE (mixed_cdft%dlb_control%recvbuff(2))
3313 NULLIFY (mixed_cdft%dlb_control%recvbuff(1)%buffs, mixed_cdft%dlb_control%recvbuff(2)%buffs)
3316 IF (mixed_cdft%dlb_control%send_work)
THEN
3317 ind = count(mixed_cdft%dlb_control%recv_work_repl) + 1
3319 CALL force_env%para_env%isend(msgin=sendbuffer, &
3320 dest=mixed_cdft%dest_list(i), &
3321 request=req_total(ind))
3325 IF (any(mixed_cdft%dlb_control%recv_work_repl))
THEN
3328 IF (mixed_cdft%dlb_control%recv_work_repl(i))
THEN
3329 ALLOCATE (mixed_cdft%dlb_control%recv_info(i)%matrix_info(6))
3330 CALL force_env%para_env%irecv(msgout=mixed_cdft%dlb_control%recv_info(i)%matrix_info, &
3331 source=mixed_cdft%source_list(i), &
3332 request=req_total(ind))
3337 IF (
ASSOCIATED(req_total))
THEN
3341 IF (mixed_cdft%dlb_control%send_work)
THEN
3342 ind = count(mixed_cdft%dlb_control%recv_work_repl) + 1
3345 mixed_cdft%dlb_control%target_list(3, :) = mixed_cdft%dlb_control%target_list(3, :) + 3*max_targets
3346 CALL force_env%para_env%isend(msgin=mixed_cdft%dlb_control%target_list, &
3347 dest=mixed_cdft%dest_list(i), &
3348 request=req_total(ind))
3352 IF (any(mixed_cdft%dlb_control%recv_work_repl))
THEN
3355 IF (mixed_cdft%dlb_control%recv_work_repl(i))
THEN
3356 ALLOCATE (mixed_cdft%dlb_control%recv_info(i)% &
3357 target_list(3, mixed_cdft%dlb_control%recv_info(i)%matrix_info(1)))
3358 CALL force_env%para_env%irecv(msgout=mixed_cdft%dlb_control%recv_info(i)%target_list, &
3359 source=mixed_cdft%source_list(i), &
3360 request=req_total(ind))
3365 IF (
ASSOCIATED(req_total))
THEN
3367 DEALLOCATE (req_total)
3369 IF (
ASSOCIATED(sendbuffer))
DEALLOCATE (sendbuffer)
3371 IF (mixed_cdft%dlb_control%send_work)
THEN
3372 ALLOCATE (req_total(count(mixed_cdft%dlb_control%recv_work_repl) + 2*count(touched)))
3373 ELSE IF (any(mixed_cdft%dlb_control%recv_work_repl))
THEN
3374 ALLOCATE (req_total(count(mixed_cdft%dlb_control%recv_work_repl)))
3376 IF (mixed_cdft%dlb_control%send_work)
THEN
3377 ind = count(mixed_cdft%dlb_control%recv_work_repl)
3378 DO j = 1,
SIZE(mixed_cdft%dest_list)
3379 IF (touched(j))
THEN
3380 ALLOCATE (sbuff(j)%iv(4 + 3*nsend_proc(j)))
3381 sbuff(j)%iv(1:4) = (/bo_conf(1, 2), bo_conf(2, 2), bo_conf(1, 3), bo_conf(2, 3)/)
3383 DO i = 1,
SIZE(mixed_cdft%dlb_control%target_list, 2)
3384 IF (mixed_cdft%dlb_control%target_list(4 + 2*(j - 1), i) .NE. uninitialized)
THEN
3385 sbuff(j)%iv(offset:offset + 2) = (/mixed_cdft%dlb_control%target_list(1, i), &
3386 mixed_cdft%dlb_control%target_list(4 + 2*(j - 1), i), &
3387 mixed_cdft%dlb_control%target_list(4 + 2*j - 1, i)/)
3391 DO ispecial = 1, my_special_work
3392 CALL force_env%para_env%isend(msgin=sbuff(j)%iv, &
3393 dest=mixed_cdft%dest_list(j) + (ispecial - 1)*force_env%para_env%num_pe/2, &
3394 request=req_total(ind + ispecial))
3396 ind = ind + my_special_work
3400 IF (any(mixed_cdft%dlb_control%recv_work_repl))
THEN
3401 ALLOCATE (mixed_cdft%dlb_control%recv_info(
SIZE(mixed_cdft%source_list)))
3402 ALLOCATE (mixed_cdft%dlb_control%recvbuff(
SIZE(mixed_cdft%source_list)))
3404 DO j = 1,
SIZE(mixed_cdft%source_list)
3405 NULLIFY (mixed_cdft%dlb_control%recv_info(j)%target_list, &
3406 mixed_cdft%dlb_control%recvbuff(j)%buffs)
3407 IF (mixed_cdft%dlb_control%recv_work_repl(j))
THEN
3408 ALLOCATE (mixed_cdft%dlb_control%recv_info(j)%matrix_info(4 + 3*nrecv(j)))
3409 CALL force_env%para_env%irecv(mixed_cdft%dlb_control%recv_info(j)%matrix_info, &
3410 source=mixed_cdft%source_list(j), &
3411 request=req_total(ind))
3416 IF (
ASSOCIATED(req_total))
THEN
3418 DEALLOCATE (req_total)
3420 IF (any(mask_send))
THEN
3421 ALLOCATE (tmp(
SIZE(mixed_cdft%dest_list) - count(mask_send)), &
3422 tmp_bo(2,
SIZE(mixed_cdft%dest_list) - count(mask_send)))
3424 DO j = 1,
SIZE(mixed_cdft%dest_list)
3425 IF (.NOT. mask_send(j))
THEN
3426 tmp(i) = mixed_cdft%dest_list(j)
3427 tmp_bo(1:2, i) = mixed_cdft%dest_list_bo(1:2, j)
3431 DEALLOCATE (mixed_cdft%dest_list, mixed_cdft%dest_list_bo)
3432 ALLOCATE (mixed_cdft%dest_list(
SIZE(tmp)), mixed_cdft%dest_list_bo(2,
SIZE(tmp)))
3433 mixed_cdft%dest_list = tmp
3434 mixed_cdft%dest_list_bo = tmp_bo
3435 DEALLOCATE (tmp, tmp_bo)
3437 IF (any(mask_recv))
THEN
3438 ALLOCATE (tmp(
SIZE(mixed_cdft%source_list) - count(mask_recv)), &
3439 tmp_bo(4,
SIZE(mixed_cdft%source_list) - count(mask_recv)))
3441 DO j = 1,
SIZE(mixed_cdft%source_list)
3442 IF (.NOT. mask_recv(j))
THEN
3443 tmp(i) = mixed_cdft%source_list(j)
3444 tmp_bo(1:4, i) = mixed_cdft%source_list_bo(1:4, j)
3448 DEALLOCATE (mixed_cdft%source_list, mixed_cdft%source_list_bo)
3449 ALLOCATE (mixed_cdft%source_list(
SIZE(tmp)), mixed_cdft%source_list_bo(4,
SIZE(tmp)))
3450 mixed_cdft%source_list = tmp
3451 mixed_cdft%source_list_bo = tmp_bo
3452 DEALLOCATE (tmp, tmp_bo)
3454 DEALLOCATE (mask_recv, mask_send)
3455 DEALLOCATE (nsend_proc, nrecv)
3456 IF (mixed_cdft%dlb_control%send_work)
THEN
3457 DO j = 1,
SIZE(mixed_cdft%dest_list)
3458 IF (touched(j))
DEALLOCATE (sbuff(j)%iv)
3460 IF (
ASSOCIATED(touched))
DEALLOCATE (touched)
3465 "MIXED%MIXED_CDFT%PRINT%PROGRAM_RUN_INFO")
3466 CALL timestop(handle)
3468 END SUBROUTINE mixed_becke_constraint_dlb
3487 SUBROUTINE mixed_becke_constraint_low(force_env, mixed_cdft, in_memory, &
3488 is_constraint, store_vectors, R12, position_vecs, &
3489 pair_dist_vecs, coefficients, catom)
3492 LOGICAL,
INTENT(IN) :: in_memory
3493 LOGICAL,
ALLOCATABLE,
DIMENSION(:),
INTENT(INOUT) :: is_constraint
3494 LOGICAL,
INTENT(IN) :: store_vectors
3495 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :), &
3496 INTENT(INOUT) :: r12, position_vecs
3497 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :, :), &
3498 INTENT(INOUT) :: pair_dist_vecs
3499 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:), &
3500 INTENT(INOUT) :: coefficients
3501 INTEGER,
ALLOCATABLE,
DIMENSION(:),
INTENT(INOUT) :: catom
3503 CHARACTER(len=*),
PARAMETER :: routinen =
'mixed_becke_constraint_low'
3505 INTEGER :: handle, i, iatom, icomm, iforce_eval, index, iounit, ip, ispecial, iwork, j, &
3506 jatom, jcomm, k, my_special_work, my_work, natom, nbuffs, nforce_eval, np(3), &
3507 nsent_total, nskipped, nwork, offset, offset_repl
3508 INTEGER,
DIMENSION(:),
POINTER :: work, work_dlb
3509 INTEGER,
DIMENSION(:, :),
POINTER :: nsent
3510 LOGICAL :: completed_recv, should_communicate
3511 LOGICAL,
ALLOCATABLE,
DIMENSION(:) :: skip_me
3512 LOGICAL,
ALLOCATABLE,
DIMENSION(:, :) :: completed
3513 REAL(kind=
dp) :: dist1, dist2, dmyexp, my1, my1_homo, &
3514 myexp, sum_cell_f_all, &
3515 sum_cell_f_constr, th, tmp_const
3516 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: cell_functions, distances, ds_dr_i, &
3518 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: d_sum_const_dr, d_sum_pm_dr, &
3519 distance_vecs, dp_i_dri
3520 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :, :) :: dp_i_drj
3521 REAL(kind=
dp),
DIMENSION(3) :: cell_v, dist_vec, dmy_dr_i, dmy_dr_j, &
3522 dr, dr1_r2, dr_i_dr, dr_ij_dr, &
3523 dr_j_dr, grid_p, r, r1, shift
3524 REAL(kind=
dp),
DIMENSION(:),
POINTER :: cutoffs
3525 REAL(kind=
dp),
DIMENSION(:, :, :),
POINTER :: cavity, weight
3526 REAL(kind=
dp),
DIMENSION(:, :, :, :),
POINTER :: gradients
3540 NULLIFY (work, req_recv, req_send, work_dlb, nsent, cutoffs, cavity, &
3541 weight, gradients, cell, subsys_mix, force_env_qs, &
3542 particle_set, particles, auxbas_pw_pool, force_env_section, &
3543 print_section, cdft_control)
3544 CALL timeset(routinen, handle)
3545 nforce_eval =
SIZE(force_env%sub_force_env)
3546 CALL force_env_get(force_env=force_env, force_env_section=force_env_section)
3549 IF (.NOT. force_env%mixed_env%do_mixed_qmmm_cdft)
THEN
3551 subsys=subsys_mix, &
3554 particles=particles, &
3555 particle_set=particle_set)
3557 DO iforce_eval = 1, nforce_eval
3558 IF (.NOT.
ASSOCIATED(force_env%sub_force_env(iforce_eval)%force_env)) cycle
3559 force_env_qs => force_env%sub_force_env(iforce_eval)%force_env
3561 CALL get_qs_env(force_env_qs%qmmm_env%qs_env, &
3562 cp_subsys=subsys_mix, &
3565 particles=particles, &
3566 particle_set=particle_set)
3568 natom =
SIZE(particles%els)
3569 cdft_control => mixed_cdft%cdft_control
3570 CALL pw_env_get(pw_env=mixed_cdft%pw_env, auxbas_pw_pool=auxbas_pw_pool)
3571 np = auxbas_pw_pool%pw_grid%npts
3572 dr = auxbas_pw_pool%pw_grid%dr
3573 shift = -real(
modulo(np, 2),
dp)*dr/2.0_dp
3574 ALLOCATE (cell_functions(natom), skip_me(natom))
3575 IF (store_vectors)
THEN
3576 ALLOCATE (distances(natom))
3577 ALLOCATE (distance_vecs(3, natom))
3580 ALLOCATE (ds_dr_j(3))
3581 ALLOCATE (ds_dr_i(3))
3582 ALLOCATE (d_sum_pm_dr(3, natom))
3583 ALLOCATE (d_sum_const_dr(3, natom))
3584 ALLOCATE (dp_i_drj(3, natom, natom))
3585 ALLOCATE (dp_i_dri(3, natom))
3588 IF (mixed_cdft%dlb)
THEN
3589 ALLOCATE (work(force_env%para_env%num_pe), work_dlb(force_env%para_env%num_pe))
3596 IF (mixed_cdft%dlb)
THEN
3597 IF (mixed_cdft%dlb_control%recv_work)
THEN
3599 IF (.NOT. mixed_cdft%is_special)
THEN
3600 ALLOCATE (req_send(2, 3))
3602 ALLOCATE (req_send(2, 3*
SIZE(mixed_cdft%dlb_control%sendbuff)))
3605 IF (any(mixed_cdft%dlb_control%recv_work_repl))
THEN
3606 IF (.NOT. mixed_cdft%is_special)
THEN
3608 IF (mixed_cdft%dlb_control%recv_work_repl(1) .AND. mixed_cdft%dlb_control%recv_work_repl(2))
THEN
3609 ALLOCATE (req_recv(3*(
SIZE(mixed_cdft%dlb_control%recv_info(1)%target_list, 2) + &
3610 SIZE(mixed_cdft%dlb_control%recv_info(2)%target_list, 2))))
3611 offset_repl = 3*
SIZE(mixed_cdft%dlb_control%recv_info(1)%target_list, 2)
3612 ELSE IF (mixed_cdft%dlb_control%recv_work_repl(1))
THEN
3613 ALLOCATE (req_recv(3*(
SIZE(mixed_cdft%dlb_control%recv_info(1)%target_list, 2))))
3615 ALLOCATE (req_recv(3*(
SIZE(mixed_cdft%dlb_control%recv_info(2)%target_list, 2))))
3620 DO j = 1,
SIZE(mixed_cdft%dlb_control%recv_work_repl)
3621 IF (mixed_cdft%dlb_control%recv_work_repl(j))
THEN
3622 nbuffs = nbuffs + (
SIZE(mixed_cdft%dlb_control%recv_info(j)%matrix_info) - 4)/3
3625 ALLOCATE (req_recv(3*nbuffs))
3627 DO j = 1,
SIZE(mixed_cdft%dlb_control%recv_work_repl)
3628 IF (mixed_cdft%dlb_control%recv_work_repl(j))
THEN
3629 IF (.NOT. mixed_cdft%is_special)
THEN
3632 ALLOCATE (mixed_cdft%dlb_control%recvbuff(j)%buffs(
SIZE(mixed_cdft%dlb_control%recv_info(j)%target_list, 2)))
3633 DO i = 1,
SIZE(mixed_cdft%dlb_control%recv_info(j)%target_list, 2)
3634 IF (mixed_cdft%is_pencil)
THEN
3635 ALLOCATE (mixed_cdft%dlb_control%recvbuff(j)%buffs(i)% &
3636 weight(mixed_cdft%dlb_control%recv_info(j)%matrix_info(4) + offset: &
3637 mixed_cdft%dlb_control%recv_info(j)%matrix_info(4) + offset + &
3638 (mixed_cdft%dlb_control%recv_info(j)%target_list(2, i) - 1), &
3639 mixed_cdft%dlb_control%recv_info(j)%matrix_info(5): &
3640 mixed_cdft%dlb_control%recv_info(j)%matrix_info(6), &
3641 mixed_cdft%dlb_control%recv_info(j)%matrix_info(2): &
3642 mixed_cdft%dlb_control%recv_info(j)%matrix_info(3)))
3643 ALLOCATE (mixed_cdft%dlb_control%recvbuff(j)%buffs(i)% &
3644 cavity(mixed_cdft%dlb_control%recv_info(j)%matrix_info(4) + offset: &
3645 mixed_cdft%dlb_control%recv_info(j)%matrix_info(4) + offset + &
3646 (mixed_cdft%dlb_control%recv_info(j)%target_list(2, i) - 1), &
3647 mixed_cdft%dlb_control%recv_info(j)%matrix_info(5): &
3648 mixed_cdft%dlb_control%recv_info(j)%matrix_info(6), &
3649 mixed_cdft%dlb_control%recv_info(j)%matrix_info(2): &
3650 mixed_cdft%dlb_control%recv_info(j)%matrix_info(3)))
3651 ALLOCATE (mixed_cdft%dlb_control%recvbuff(j)%buffs(i)% &
3652 gradients(3*natom, &
3653 mixed_cdft%dlb_control%recv_info(j)%matrix_info(4) + offset: &
3654 mixed_cdft%dlb_control%recv_info(j)%matrix_info(4) + offset + &
3655 (mixed_cdft%dlb_control%recv_info(j)%target_list(2, i) - 1), &
3656 mixed_cdft%dlb_control%recv_info(j)%matrix_info(5): &
3657 mixed_cdft%dlb_control%recv_info(j)%matrix_info(6), &
3658 mixed_cdft%dlb_control%recv_info(j)%matrix_info(2): &
3659 mixed_cdft%dlb_control%recv_info(j)%matrix_info(3)))
3661 ALLOCATE (mixed_cdft%dlb_control%recvbuff(j)%buffs(i)% &
3662 weight(mixed_cdft%dlb_control%recv_info(j)%matrix_info(5): &
3663 mixed_cdft%dlb_control%recv_info(j)%matrix_info(6), &
3664 mixed_cdft%dlb_control%recv_info(j)%matrix_info(4) + offset: &
3665 mixed_cdft%dlb_control%recv_info(j)%matrix_info(4) + offset + &
3666 (mixed_cdft%dlb_control%recv_info(j)%target_list(2, i) - 1), &
3667 mixed_cdft%dlb_control%recv_info(j)%matrix_info(2): &
3668 mixed_cdft%dlb_control%recv_info(j)%matrix_info(3)))
3669 ALLOCATE (mixed_cdft%dlb_control%recvbuff(j)%buffs(i)% &
3670 cavity(mixed_cdft%dlb_control%recv_info(j)%matrix_info(5): &
3671 mixed_cdft%dlb_control%recv_info(j)%matrix_info(6), &
3672 mixed_cdft%dlb_control%recv_info(j)%matrix_info(4) + offset: &
3673 mixed_cdft%dlb_control%recv_info(j)%matrix_info(4) + offset + &
3674 (mixed_cdft%dlb_control%recv_info(j)%target_list(2, i) - 1), &
3675 mixed_cdft%dlb_control%recv_info(j)%matrix_info(2): &
3676 mixed_cdft%dlb_control%recv_info(j)%matrix_info(3)))
3677 ALLOCATE (mixed_cdft%dlb_control%recvbuff(j)%buffs(i)% &
3678 gradients(3*natom, &
3679 mixed_cdft%dlb_control%recv_info(j)%matrix_info(5): &
3680 mixed_cdft%dlb_control%recv_info(j)%matrix_info(6), &
3681 mixed_cdft%dlb_control%recv_info(j)%matrix_info(4) + offset: &
3682 mixed_cdft%dlb_control%recv_info(j)%matrix_info(4) + offset + &
3683 (mixed_cdft%dlb_control%recv_info(j)%target_list(2, i) - 1), &
3684 mixed_cdft%dlb_control%recv_info(j)%matrix_info(2): &
3685 mixed_cdft%dlb_control%recv_info(j)%matrix_info(3)))
3688 CALL force_env%para_env%irecv(msgout=mixed_cdft%dlb_control%recvbuff(j)%buffs(i)%cavity, &
3689 source=mixed_cdft%dlb_control%recv_info(j)%target_list(1, i), &
3690 request=req_recv(3*(i - 1) + (j - 1)*offset_repl + 1), &
3691 tag=mixed_cdft%dlb_control%recv_info(j)%target_list(3, i))
3692 CALL force_env%para_env%irecv(msgout=mixed_cdft%dlb_control%recvbuff(j)%buffs(i)%weight, &
3693 source=mixed_cdft%dlb_control%recv_info(j)%target_list(1, i), &
3694 request=req_recv(3*(i - 1) + (j - 1)*offset_repl + 2), &
3695 tag=mixed_cdft%dlb_control%recv_info(j)%target_list(3, i) + 1)
3696 CALL force_env%para_env%irecv(msgout=mixed_cdft%dlb_control%recvbuff(j)%buffs(i)%gradients, &
3697 source=mixed_cdft%dlb_control%recv_info(j)%target_list(1, i), &
3698 request=req_recv(3*(i - 1) + (j - 1)*offset_repl + 3), &
3699 tag=mixed_cdft%dlb_control%recv_info(j)%target_list(3, i) + 2)
3700 offset = offset + mixed_cdft%dlb_control%recv_info(j)%target_list(2, i)
3702 DEALLOCATE (mixed_cdft%dlb_control%recv_info(j)%matrix_info)
3704 ALLOCATE (mixed_cdft%dlb_control%recvbuff(j)% &
3705 buffs((
SIZE(mixed_cdft%dlb_control%recv_info(j)%matrix_info) - 4)/3))
3707 DO i = 1,
SIZE(mixed_cdft%dlb_control%recvbuff(j)%buffs)
3708 ALLOCATE (mixed_cdft%dlb_control%recvbuff(j)%buffs(i)% &
3709 weight(mixed_cdft%dlb_control%recv_info(j)%matrix_info(index): &
3710 mixed_cdft%dlb_control%recv_info(j)%matrix_info(index + 1), &
3711 mixed_cdft%dlb_control%recv_info(j)%matrix_info(1): &
3712 mixed_cdft%dlb_control%recv_info(j)%matrix_info(2), &
3713 mixed_cdft%dlb_control%recv_info(j)%matrix_info(3): &
3714 mixed_cdft%dlb_control%recv_info(j)%matrix_info(4)))
3715 ALLOCATE (mixed_cdft%dlb_control%recvbuff(j)%buffs(i)% &
3716 cavity(mixed_cdft%dlb_control%recv_info(j)%matrix_info(index): &
3717 mixed_cdft%dlb_control%recv_info(j)%matrix_info(index + 1), &
3718 mixed_cdft%dlb_control%recv_info(j)%matrix_info(1): &
3719 mixed_cdft%dlb_control%recv_info(j)%matrix_info(2), &
3720 mixed_cdft%dlb_control%recv_info(j)%matrix_info(3): &
3721 mixed_cdft%dlb_control%recv_info(j)%matrix_info(4)))
3722 ALLOCATE (mixed_cdft%dlb_control%recvbuff(j)%buffs(i)% &
3723 gradients(3*natom, mixed_cdft%dlb_control%recv_info(j)%matrix_info(index): &
3724 mixed_cdft%dlb_control%recv_info(j)%matrix_info(index + 1), &
3725 mixed_cdft%dlb_control%recv_info(j)%matrix_info(1): &
3726 mixed_cdft%dlb_control%recv_info(j)%matrix_info(2), &
3727 mixed_cdft%dlb_control%recv_info(j)%matrix_info(3): &
3728 mixed_cdft%dlb_control%recv_info(j)%matrix_info(4)))
3729 CALL force_env%para_env%irecv(msgout=mixed_cdft%dlb_control%recvbuff(j)%buffs(i)%cavity, &
3730 source=mixed_cdft%dlb_control%recv_info(j)%matrix_info(index - 1), &
3731 request=req_recv(offset_repl), tag=1)
3732 CALL force_env%para_env%irecv(msgout=mixed_cdft%dlb_control%recvbuff(j)%buffs(i)%weight, &
3733 source=mixed_cdft%dlb_control%recv_info(j)%matrix_info(index - 1), &
3734 request=req_recv(offset_repl + 1), tag=2)
3735 CALL force_env%para_env%irecv(msgout=mixed_cdft%dlb_control%recvbuff(j)%buffs(i)%gradients, &
3736 source=mixed_cdft%dlb_control%recv_info(j)%matrix_info(index - 1), &
3737 request=req_recv(offset_repl + 2), tag=3)
3739 offset_repl = offset_repl + 3
3741 DEALLOCATE (mixed_cdft%dlb_control%recv_info(j)%matrix_info)
3747 cutoffs => cdft_control%becke_control%cutoffs
3748 should_communicate = .false.
3750 cell_v(i) = cell%hmat(i, i)
3752 DO iwork = my_work, 1, -1
3753 IF (iwork == 2)
THEN
3754 IF (.NOT. mixed_cdft%is_special)
THEN
3755 cavity => mixed_cdft%dlb_control%cavity
3756 weight => mixed_cdft%dlb_control%weight
3757 gradients => mixed_cdft%dlb_control%gradients
3758 ALLOCATE (completed(2, 3), nsent(2, 3))
3760 my_special_work =
SIZE(mixed_cdft%dlb_control%sendbuff)
3761 ALLOCATE (completed(2, 3*my_special_work), nsent(2, 3*my_special_work))
3766 IF (.NOT. mixed_cdft%is_special)
THEN
3767 weight => mixed_cdft%weight
3768 cavity => mixed_cdft%cavity
3769 gradients => cdft_control%group(1)%gradients
3771 my_special_work =
SIZE(mixed_cdft%dest_list)
3774 DO ispecial = 1, my_special_work
3776 IF (mixed_cdft%is_special)
THEN
3777 IF (iwork == 1)
THEN
3778 weight => mixed_cdft%sendbuff(ispecial)%weight
3779 cavity => mixed_cdft%sendbuff(ispecial)%cavity
3780 gradients => mixed_cdft%sendbuff(ispecial)%gradients
3782 weight => mixed_cdft%dlb_control%sendbuff(ispecial)%weight
3783 cavity => mixed_cdft%dlb_control%sendbuff(ispecial)%cavity
3784 gradients => mixed_cdft%dlb_control%sendbuff(ispecial)%gradients
3787 DO k = lbound(weight, 1), ubound(weight, 1)
3788 IF (mixed_cdft%dlb .AND. mixed_cdft%is_pencil .AND. .NOT. mixed_cdft%is_special)
THEN
3789 IF (mixed_cdft%dlb_control%send_work)
THEN
3790 IF (k .GE. mixed_cdft%dlb_control%distributed(1) .AND. &
3791 k .LE. mixed_cdft%dlb_control%distributed(2))
THEN
3796 DO j = lbound(weight, 2), ubound(weight, 2)
3797 IF (mixed_cdft%dlb .AND. .NOT. mixed_cdft%is_pencil .AND. .NOT. mixed_cdft%is_special)
THEN
3798 IF (mixed_cdft%dlb_control%send_work)
THEN
3799 IF (j .GE. mixed_cdft%dlb_control%distributed(1) .AND. &
3800 j .LE. mixed_cdft%dlb_control%distributed(2))
THEN
3806 IF (should_communicate)
THEN
3807 DO icomm = 1,
SIZE(nsent, 2)
3808 DO jcomm = 1,
SIZE(nsent, 1)
3809 IF (nsent(jcomm, icomm) == 1) cycle
3810 completed(jcomm, icomm) = req_send(jcomm, icomm)%test()
3811 IF (completed(jcomm, icomm))
THEN
3812 nsent(jcomm, icomm) = nsent(jcomm, icomm) + 1
3813 nsent_total = nsent_total + 1
3814 IF (nsent_total ==
SIZE(nsent, 1)*
SIZE(nsent, 2)) should_communicate = .false.
3816 IF (all(completed(:, icomm)))
THEN
3817 IF (
modulo(icomm, 3) == 1)
THEN
3818 IF (.NOT. mixed_cdft%is_special)
THEN
3819 DEALLOCATE (mixed_cdft%dlb_control%cavity)
3821 DEALLOCATE (mixed_cdft%dlb_control%sendbuff((icomm - 1)/3 + 1)%cavity)
3823 ELSE IF (
modulo(icomm, 3) == 2)
THEN
3824 IF (.NOT. mixed_cdft%is_special)
THEN
3825 DEALLOCATE (mixed_cdft%dlb_control%weight)
3827 DEALLOCATE (mixed_cdft%dlb_control%sendbuff((icomm - 1)/3 + 1)%weight)
3830 IF (.NOT. mixed_cdft%is_special)
THEN
3831 DEALLOCATE (mixed_cdft%dlb_control%gradients)
3833 DEALLOCATE (mixed_cdft%dlb_control%sendbuff((icomm - 1)/3 + 1)%gradients)
3841 IF (
ASSOCIATED(req_recv)) &
3844 DO i = lbound(weight, 3), ubound(weight, 3)
3845 IF (cdft_control%becke_control%cavity_confine)
THEN
3846 IF (cavity(k, j, i) < cdft_control%becke_control%eps_cavity) cycle
3848 grid_p(1) = k*dr(1) + shift(1)
3849 grid_p(2) = j*dr(2) + shift(2)
3850 grid_p(3) = i*dr(3) + shift(3)
3852 cell_functions = 1.0_dp
3854 IF (store_vectors) distances = 0.0_dp
3856 d_sum_pm_dr = 0.0_dp
3857 d_sum_const_dr = 0.0_dp
3861 IF (skip_me(iatom))
THEN
3862 cell_functions(iatom) = 0.0_dp
3863 IF (cdft_control%becke_control%should_skip)
THEN
3864 IF (is_constraint(iatom)) nskipped = nskipped + 1
3865 IF (nskipped == cdft_control%natoms)
THEN
3867 IF (cdft_control%becke_control%cavity_confine)
THEN
3868 cavity(k, j, i) = 0.0_dp
3876 IF (store_vectors)
THEN
3877 IF (distances(iatom) .EQ. 0.0_dp)
THEN
3878 r = position_vecs(:, iatom)
3879 dist_vec = (r - grid_p) - anint((r - grid_p)/cell_v)*cell_v
3880 dist1 = sqrt(dot_product(dist_vec, dist_vec))
3881 distance_vecs(:, iatom) = dist_vec
3882 distances(iatom) = dist1
3884 dist_vec = distance_vecs(:, iatom)
3885 dist1 = distances(iatom)
3888 r = particle_set(iatom)%r
3890 r(ip) =
modulo(r(ip), cell%hmat(ip, ip)) - cell%hmat(ip, ip)/2._dp
3892 dist_vec = (r - grid_p) - anint((r - grid_p)/cell_v)*cell_v
3893 dist1 = sqrt(dot_product(dist_vec, dist_vec))
3895 IF (dist1 .LE. cutoffs(iatom))
THEN
3897 IF (dist1 .LE. th) dist1 = th
3898 dr_i_dr(:) = dist_vec(:)/dist1
3901 IF (jatom .NE. iatom)
THEN
3902 IF (jatom < iatom)
THEN
3903 IF (.NOT. skip_me(jatom)) cycle
3905 IF (store_vectors)
THEN
3906 IF (distances(jatom) .EQ. 0.0_dp)
THEN
3907 r1 = position_vecs(:, jatom)
3908 dist_vec = (r1 - grid_p) - anint((r1 - grid_p)/cell_v)*cell_v
3909 dist2 = sqrt(dot_product(dist_vec, dist_vec))
3910 distance_vecs(:, jatom) = dist_vec
3911 distances(jatom) = dist2
3913 dist_vec = distance_vecs(:, jatom)
3914 dist2 = distances(jatom)
3917 r1 = particle_set(jatom)%r
3919 r1(ip) =
modulo(r1(ip), cell%hmat(ip, ip)) - cell%hmat(ip, ip)/2._dp
3921 dist_vec = (r1 - grid_p) - anint((r1 - grid_p)/cell_v)*cell_v
3922 dist2 = sqrt(dot_product(dist_vec, dist_vec))
3925 IF (store_vectors)
THEN
3926 dr1_r2 = pair_dist_vecs(:, iatom, jatom)
3928 dr1_r2 = (r - r1) - anint((r - r1)/cell_v)*cell_v
3930 IF (dist2 .LE. th) dist2 = th
3931 tmp_const = (r12(iatom, jatom)**3)
3932 dr_ij_dr(:) = dr1_r2(:)/tmp_const
3934 dr_j_dr = dist_vec(:)/dist2
3935 dmy_dr_j(:) = -(dr_j_dr(:)/r12(iatom, jatom) - (dist1 - dist2)*dr_ij_dr(:))
3937 dmy_dr_i(:) = dr_i_dr(:)/r12(iatom, jatom) - (dist1 - dist2)*dr_ij_dr(:)
3939 my1 = (dist1 - dist2)/r12(iatom, jatom)
3940 IF (cdft_control%becke_control%adjust)
THEN
3943 cdft_control%becke_control%aij(iatom, jatom)*(1.0_dp - my1**2)
3945 myexp = 1.5_dp*my1 - 0.5_dp*my1**3
3947 dmyexp = 1.5_dp - 1.5_dp*my1**2
3948 tmp_const = (1.5_dp**2)*dmyexp*(1 - myexp**2)* &
3949 (1.0_dp - ((1.5_dp*myexp - 0.5_dp*(myexp**3))**2))
3951 ds_dr_i(:) = -0.5_dp*tmp_const*dmy_dr_i(:)
3952 ds_dr_j(:) = -0.5_dp*tmp_const*dmy_dr_j(:)
3953 IF (cdft_control%becke_control%adjust)
THEN
3954 tmp_const = 1.0_dp - 2.0_dp*my1_homo*cdft_control%becke_control%aij(iatom, jatom)
3955 ds_dr_i(:) = ds_dr_i(:)*tmp_const
3956 ds_dr_j(:) = ds_dr_j(:)*tmp_const
3959 myexp = 1.5_dp*myexp - 0.5_dp*myexp**3
3960 myexp = 1.5_dp*myexp - 0.5_dp*myexp**3
3961 tmp_const = 0.5_dp*(1.0_dp - myexp)
3962 cell_functions(iatom) = cell_functions(iatom)*tmp_const
3964 IF (abs(tmp_const) .LE. th) tmp_const = tmp_const + th
3965 dp_i_dri(:, iatom) = dp_i_dri(:, iatom) + ds_dr_i(:)/tmp_const
3966 dp_i_drj(:, iatom, jatom) = ds_dr_j(:)/tmp_const
3969 IF (dist2 .LE. cutoffs(jatom))
THEN
3970 tmp_const = 0.5_dp*(1.0_dp + myexp)
3971 cell_functions(jatom) = cell_functions(jatom)*tmp_const
3973 IF (abs(tmp_const) .LE. th) tmp_const = tmp_const + th
3974 dp_i_drj(:, jatom, iatom) = -ds_dr_i(:)/tmp_const
3975 dp_i_dri(:, jatom) = dp_i_dri(:, jatom) - ds_dr_j(:)/tmp_const
3978 skip_me(jatom) = .true.
3983 dp_i_dri(:, iatom) = cell_functions(iatom)*dp_i_dri(:, iatom)
3984 d_sum_pm_dr(:, iatom) = d_sum_pm_dr(:, iatom) + dp_i_dri(:, iatom)
3985 IF (is_constraint(iatom)) &
3986 d_sum_const_dr(:, iatom) = d_sum_const_dr(:, iatom) + dp_i_dri(:, iatom)* &
3989 IF (jatom .NE. iatom)
THEN
3990 IF (jatom < iatom)
THEN
3991 IF (.NOT. skip_me(jatom))
THEN
3992 dp_i_drj(:, iatom, jatom) = cell_functions(iatom)*dp_i_drj(:, iatom, jatom)
3993 d_sum_pm_dr(:, jatom) = d_sum_pm_dr(:, jatom) + dp_i_drj(:, iatom, jatom)
3994 IF (is_constraint(iatom)) &
3995 d_sum_const_dr(:, jatom) = d_sum_const_dr(:, jatom) + &
3996 dp_i_drj(:, iatom, jatom)* &
4001 dp_i_drj(:, iatom, jatom) = cell_functions(iatom)*dp_i_drj(:, iatom, jatom)
4002 d_sum_pm_dr(:, jatom) = d_sum_pm_dr(:, jatom) + dp_i_drj(:, iatom, jatom)
4003 IF (is_constraint(iatom)) &
4004 d_sum_const_dr(:, jatom) = d_sum_const_dr(:, jatom) + dp_i_drj(:, iatom, jatom)* &
4010 cell_functions(iatom) = 0.0_dp
4011 skip_me(iatom) = .true.
4012 IF (cdft_control%becke_control%should_skip)
THEN
4013 IF (is_constraint(iatom)) nskipped = nskipped + 1
4014 IF (nskipped == cdft_control%natoms)
THEN
4016 IF (cdft_control%becke_control%cavity_confine)
THEN
4017 cavity(k, j, i) = 0.0_dp
4025 IF (nskipped == cdft_control%natoms) cycle
4026 sum_cell_f_constr = 0.0_dp
4027 DO ip = 1, cdft_control%natoms
4028 sum_cell_f_constr = sum_cell_f_constr + cell_functions(catom(ip))* &
4029 cdft_control%group(1)%coeff(ip)
4031 sum_cell_f_all = 0.0_dp
4034 sum_cell_f_all = sum_cell_f_all + cell_functions(ip)
4038 IF (abs(sum_cell_f_all) .GT. 0.0_dp)
THEN
4039 gradients(3*(iatom - 1) + 1:3*(iatom - 1) + 3, k, j, i) = &
4040 d_sum_const_dr(:, iatom)/sum_cell_f_all - sum_cell_f_constr* &
4041 d_sum_pm_dr(:, iatom)/(sum_cell_f_all**2)
4045 IF (abs(sum_cell_f_all) .GT. 0.000001) &
4046 weight(k, j, i) = sum_cell_f_constr/sum_cell_f_all
4051 IF (iwork == 2)
THEN
4052 IF (.NOT. mixed_cdft%is_special)
THEN
4053 DO i = 1,
SIZE(req_send, 1)
4054 CALL force_env%para_env%isend(msgin=mixed_cdft%dlb_control%cavity, &
4055 dest=mixed_cdft%dlb_control%my_dest_repl(i), &
4056 request=req_send(i, 1), &
4057 tag=mixed_cdft%dlb_control%dest_tags_repl(i))
4058 CALL force_env%para_env%isend(msgin=mixed_cdft%dlb_control%weight, &
4059 dest=mixed_cdft%dlb_control%my_dest_repl(i), &
4060 request=req_send(i, 2), &
4061 tag=mixed_cdft%dlb_control%dest_tags_repl(i) + 1)
4062 CALL force_env%para_env%isend(msgin=mixed_cdft%dlb_control%gradients, &
4063 dest=mixed_cdft%dlb_control%my_dest_repl(i), &
4064 request=req_send(i, 3), &
4065 tag=mixed_cdft%dlb_control%dest_tags_repl(i) + 2)
4067 should_communicate = .true.
4070 DO i = 1,
SIZE(req_send, 1)
4071 CALL force_env%para_env%isend(msgin=mixed_cdft%dlb_control%sendbuff(ispecial)%cavity, &
4072 dest=mixed_cdft%dlb_control%sendbuff(ispecial)%rank(i), &
4073 request=req_send(i, 3*(ispecial - 1) + 1), tag=1)
4074 CALL force_env%para_env%isend(msgin=mixed_cdft%dlb_control%sendbuff(ispecial)%weight, &
4075 dest=mixed_cdft%dlb_control%sendbuff(ispecial)%rank(i), &
4076 request=req_send(i, 3*(ispecial - 1) + 2), tag=2)
4077 CALL force_env%para_env%isend(msgin=mixed_cdft%dlb_control%sendbuff(ispecial)%gradients, &
4078 dest=mixed_cdft%dlb_control%sendbuff(ispecial)%rank(i), &
4079 request=req_send(i, 3*(ispecial - 1) + 3), tag=3)
4081 IF (ispecial .EQ. my_special_work)
THEN
4082 should_communicate = .true.
4086 work(mixed_cdft%dlb_control%my_source + 1) = work(mixed_cdft%dlb_control%my_source + 1) + nwork
4087 work_dlb(force_env%para_env%mepos + 1) = work_dlb(force_env%para_env%mepos + 1) + nwork
4089 IF (mixed_cdft%dlb) work(force_env%para_env%mepos + 1) = work(force_env%para_env%mepos + 1) + nwork
4090 IF (mixed_cdft%dlb) work_dlb(force_env%para_env%mepos + 1) = work_dlb(force_env%para_env%mepos + 1) + nwork
4095 IF (mixed_cdft%dlb)
THEN
4096 IF (mixed_cdft%dlb_control%recv_work .AND. &
4097 any(mixed_cdft%dlb_control%recv_work_repl))
THEN
4098 ALLOCATE (req_total(
SIZE(req_recv) +
SIZE(req_send, 1)*
SIZE(req_send, 2)))
4099 index =
SIZE(req_recv)
4100 req_total(1:index) = req_recv
4101 DO i = 1,
SIZE(req_send, 2)
4102 DO j = 1,
SIZE(req_send, 1)
4104 req_total(index) = req_send(j, i)
4108 DEALLOCATE (req_total)
4109 IF (
ASSOCIATED(mixed_cdft%dlb_control%cavity)) &
4110 DEALLOCATE (mixed_cdft%dlb_control%cavity)
4111 IF (
ASSOCIATED(mixed_cdft%dlb_control%weight)) &
4112 DEALLOCATE (mixed_cdft%dlb_control%weight)
4113 IF (
ASSOCIATED(mixed_cdft%dlb_control%gradients)) &
4114 DEALLOCATE (mixed_cdft%dlb_control%gradients)
4115 IF (mixed_cdft%is_special)
THEN
4116 DO j = 1,
SIZE(mixed_cdft%dlb_control%sendbuff)
4117 IF (
ASSOCIATED(mixed_cdft%dlb_control%sendbuff(j)%cavity)) &
4118 DEALLOCATE (mixed_cdft%dlb_control%sendbuff(j)%cavity)
4119 IF (
ASSOCIATED(mixed_cdft%dlb_control%sendbuff(j)%weight)) &
4120 DEALLOCATE (mixed_cdft%dlb_control%sendbuff(j)%weight)
4121 IF (
ASSOCIATED(mixed_cdft%dlb_control%sendbuff(j)%gradients)) &
4122 DEALLOCATE (mixed_cdft%dlb_control%sendbuff(j)%gradients)
4124 DEALLOCATE (mixed_cdft%dlb_control%sendbuff)
4126 DEALLOCATE (req_send, req_recv)
4127 ELSE IF (mixed_cdft%dlb_control%recv_work)
THEN
4128 IF (should_communicate)
THEN
4131 IF (
ASSOCIATED(mixed_cdft%dlb_control%cavity)) &
4132 DEALLOCATE (mixed_cdft%dlb_control%cavity)
4133 IF (
ASSOCIATED(mixed_cdft%dlb_control%weight)) &
4134 DEALLOCATE (mixed_cdft%dlb_control%weight)
4135 IF (
ASSOCIATED(mixed_cdft%dlb_control%gradients)) &
4136 DEALLOCATE (mixed_cdft%dlb_control%gradients)
4137 IF (mixed_cdft%is_special)
THEN
4138 DO j = 1,
SIZE(mixed_cdft%dlb_control%sendbuff)
4139 IF (
ASSOCIATED(mixed_cdft%dlb_control%sendbuff(j)%cavity)) &
4140 DEALLOCATE (mixed_cdft%dlb_control%sendbuff(j)%cavity)
4141 IF (
ASSOCIATED(mixed_cdft%dlb_control%sendbuff(j)%weight)) &
4142 DEALLOCATE (mixed_cdft%dlb_control%sendbuff(j)%weight)
4143 IF (
ASSOCIATED(mixed_cdft%dlb_control%sendbuff(j)%gradients)) &
4144 DEALLOCATE (mixed_cdft%dlb_control%sendbuff(j)%gradients)
4146 DEALLOCATE (mixed_cdft%dlb_control%sendbuff)
4148 DEALLOCATE (req_send)
4149 ELSE IF (any(mixed_cdft%dlb_control%recv_work_repl))
THEN
4151 DEALLOCATE (req_recv)
4154 IF (mixed_cdft%dlb)
THEN
4155 CALL force_env%para_env%sum(work)
4156 CALL force_env%para_env%sum(work_dlb)
4157 IF (.NOT.
ASSOCIATED(mixed_cdft%dlb_control%prediction_error)) &
4158 ALLOCATE (mixed_cdft%dlb_control%prediction_error(force_env%para_env%num_pe))
4159 mixed_cdft%dlb_control%prediction_error = mixed_cdft%dlb_control%expected_work - work
4160 IF (debug_this_module .AND. iounit > 0)
THEN
4161 DO i = 1,
SIZE(work, 1)
4162 WRITE (iounit,
'(A,I10,I10,I10)') &
4163 'Work', work(i), work_dlb(i), mixed_cdft%dlb_control%expected_work(i)
4166 DEALLOCATE (work, work_dlb, mixed_cdft%dlb_control%expected_work)
4168 NULLIFY (gradients, weight, cavity)
4169 IF (
ALLOCATED(coefficients)) &
4170 DEALLOCATE (coefficients)
4172 DEALLOCATE (ds_dr_j)
4173 DEALLOCATE (ds_dr_i)
4174 DEALLOCATE (d_sum_pm_dr)
4175 DEALLOCATE (d_sum_const_dr)
4176 DEALLOCATE (dp_i_drj)
4177 DEALLOCATE (dp_i_dri)
4179 IF (store_vectors)
THEN
4180 DEALLOCATE (pair_dist_vecs)
4184 IF (
ALLOCATED(is_constraint)) &
4185 DEALLOCATE (is_constraint)
4188 DEALLOCATE (cell_functions)
4189 DEALLOCATE (skip_me)
4190 IF (
ALLOCATED(completed)) &
4191 DEALLOCATE (completed)
4192 IF (
ASSOCIATED(nsent)) &
4194 IF (store_vectors)
THEN
4195 DEALLOCATE (distances)
4196 DEALLOCATE (distance_vecs)
4197 DEALLOCATE (position_vecs)
4199 IF (
ASSOCIATED(req_send)) &
4200 DEALLOCATE (req_send)
4201 IF (
ASSOCIATED(req_recv)) &
4202 DEALLOCATE (req_recv)
4204 "MIXED%MIXED_CDFT%PRINT%PROGRAM_RUN_INFO")
4205 CALL timestop(handle)
4207 END SUBROUTINE mixed_becke_constraint_low
static GRID_HOST_DEVICE int modulo(int a, int m)
Equivalent of Fortran's MODULO, which always return a positive number. https://gcc....
All kind of helpful little routines.
real(kind=dp) function, public exp_radius_very_extended(la_min, la_max, lb_min, lb_max, pab, o1, o2, ra, rb, rp, zetp, eps, prefactor, cutoff, epsabs)
computes the radius of the Gaussian outside of which it is smaller than eps
Define the atomic kind types and their sub types.
subroutine, public get_atomic_kind(atomic_kind, fist_potential, element_symbol, name, mass, kind_number, natom, atom_list, rcov, rvdw, z, qeff, apol, cpol, mm_radius, shell, shell_active, damping)
Get attributes of an atomic kind.
Handles all functions related to the CELL.
various utilities that regard array of different kinds: output, allocation,... maybe it is not a good...
Defines control structures, which contain the parameters and the settings for the DFT-based calculati...
subroutine, public dbcsr_release_p(matrix)
...
subroutine, public dbcsr_scale(matrix, alpha_scalar)
...
subroutine, public dbcsr_copy(matrix_b, matrix_a, name, keep_sparsity, keep_imaginary)
...
subroutine, public dbcsr_init_p(matrix)
...
subroutine, public dbcsr_release(matrix)
...
subroutine, public dbcsr_add(matrix_a, matrix_b, alpha_scalar, beta_scalar)
...
Interface to (sca)lapack for the Cholesky based procedures.
subroutine, public cp_dbcsr_syevd(matrix, eigenvectors, eigenvalues, para_env, blacs_env)
...
DBCSR operations in CP2K.
subroutine, public cp_dbcsr_sm_fm_multiply(matrix, fm_in, fm_out, ncol, alpha, beta)
multiply a dbcsr with a fm matrix
Basic linear algebra operations for full matrices.
subroutine, public cp_fm_column_scale(matrixa, scaling)
scales column i of matrix a with scaling(i)
subroutine, public cp_fm_transpose(matrix, matrixt)
transposes a matrix matrixt = matrix ^ T
subroutine, public cp_fm_invert(matrix_a, matrix_inverse, det_a, eps_svd, eigval)
Inverts a cp_fm_type matrix, optionally returning the determinant of the input matrix.
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
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_set_all(matrix, alpha, beta)
set all elements of a matrix to the same value, and optionally the diagonal to a different one
subroutine, public cp_fm_create(matrix, matrix_struct, name, use_sp)
creates a new full matrix with the given structure
subroutine, public cp_fm_write_formatted(fm, unit, header, value_format)
Write out a full matrix in plain text.
various routines to log and control the output. The idea is that decisions about where to log should ...
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,...
A wrapper around pw_to_cube() which accepts particle_list_type.
subroutine, public cp_pw_to_cube(pw, unit_nr, title, particles, stride, zero_tails, silent, mpi_io)
...
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
real(kind=dp) function, public cp_unit_from_cp2k(value, unit_str, defaults, power)
converts from the internal cp2k units to the given unit
Interface for the force calculations.
integer, parameter, public use_qmmm
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
integer, parameter, public use_qmmmx
integer, parameter, public use_qs_force
Fortran API for the grid package, which is written in C.
integer, parameter, public grid_func_ab
subroutine, public collocate_pgf_product(la_max, zeta, la_min, lb_max, zetb, lb_min, ra, rab, scale, pab, o1, o2, rsgrid, ga_gb_function, radius, use_subpatch, subpatch_pattern)
low level collocation of primitive gaussian functions
Calculate Hirshfeld charges and related functions.
subroutine, public create_shape_function(hirshfeld_env, qs_kind_set, atomic_kind_set, radius, radii_list)
creates kind specific shape functions for Hirshfeld charges
The types needed for the calculation of Hirshfeld charges and related functions.
Defines the basic variable types.
integer, parameter, public dp
integer, parameter, public default_path_length
Machine interface based on Fortran 2003 and POSIX.
real(kind=dp) function, public m_walltime()
returns time from a real-time clock, protected against rolling early/easily
Collection of simple mathematical functions and subroutines.
subroutine, public diamat_all(a, eigval, dac)
Diagonalize the symmetric n by n matrix a using the LAPACK library. Only the upper triangle of matrix...
Utility routines for the memory handling.
Interface to the message passing library MPI.
Methods for mixed CDFT calculations.
subroutine, public mixed_cdft_calculate_coupling(force_env)
Driver routine to calculate the electronic coupling(s) between CDFT states.
subroutine, public mixed_cdft_build_weight(force_env, calculate_forces, iforce_eval)
Driver routine to handle the build of CDFT weight/gradient in parallel and serial modes.
subroutine, public mixed_cdft_init(force_env, calculate_forces)
Initialize a mixed CDFT calculation.
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_type_create(cdft_control)
inits the given mixed_cdft_type
subroutine, public mixed_cdft_work_type_release(matrix)
Releases arrays within the mixed CDFT work matrix container.
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.
subroutine, public set_mixed_env(mixed_env, atomic_kind_set, particle_set, local_particles, local_molecules, molecule_kind_set, molecule_set, cell_ref, mixed_energy, subsys, input, sub_para_env, cdft_control)
Set the MIXED environment.
basic linear algebra operations for full matrixes
represent a simple array based list of the given type
Define the data structure for the particle information.
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
Manages a pool of grids (to be used for example as tmp objects), but can also be used to instantiate ...
Defines CDFT control structures.
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, sab_cneo, particle_set, energy, force, matrix_h, matrix_h_im, matrix_ks, matrix_ks_im, matrix_vxc, run_rtp, rtp, matrix_h_kp, matrix_h_im_kp, matrix_ks_kp, matrix_ks_im_kp, matrix_vxc_kp, kinetic_kp, matrix_s_kp, matrix_w_kp, matrix_s_ri_aux_kp, matrix_s, matrix_s_ri_aux, matrix_w, matrix_p_mp2, matrix_p_mp2_admm, rho, rho_xc, pw_env, ewald_env, ewald_pw, active_space, mpools, input, para_env, blacs_env, scf_control, rel_control, kinetic, qs_charges, vppl, rho_core, rho_nlcc, rho_nlcc_g, ks_env, ks_qmmm_env, wf_history, scf_env, local_particles, local_molecules, distribution_2d, dbcsr_dist, molecule_kind_set, molecule_set, subsys, cp_subsys, oce, local_rho_set, rho_atom_set, task_list, task_list_soft, rho0_atom_set, rho0_mpole, rhoz_set, rhoz_cneo_set, ecoul_1c, rho0_s_rs, rho0_s_gs, rhoz_cneo_s_rs, rhoz_cneo_s_gs, do_kpoints, has_unit_metric, requires_mo_derivs, mo_derivs, mo_loc_history, nkind, natom, nelectron_total, nelectron_spin, efield, neighbor_list_id, linres_control, xas_env, virial, cp_ddapc_env, cp_ddapc_ewald, outer_scf_history, outer_scf_ihistory, x_data, et_coupling, dftb_potential, results, se_taper, se_store_int_env, se_nddo_mpole, se_nonbond_env, admm_env, lri_env, lri_density, exstate_env, ec_env, harris_env, dispersion_env, gcp_env, vee, rho_external, external_vxc, mask, mp2_env, bs_env, kg_env, wanniercentres, atprop, ls_scf_env, do_transport, transport_env, v_hartree_rspace, s_mstruct_changed, rho_changed, potential_changed, forces_up_to_date, mscfg_env, almo_scf_env, gradient_history, variable_history, embed_pot, spin_embed_pot, polar_env, mos_last_converged, eeq, rhs, do_rixs, tb_tblite)
Get the QUICKSTEP environment.
Define the quickstep kind type and their sub types.
Definition and initialisation of the mo data type.
subroutine, public wfn_restart_file_name(filename, exist, section, logger, kp, xas, rtp)
...
subroutine, public read_mo_set_from_restart(mo_array, qs_kind_set, particle_set, para_env, id_nr, multiplicity, dft_section, natom_mismatch, cdft, out_unit)
...
collects routines that perform operations directly related to MOs
subroutine, public make_basis_simple(vmatrix, ncol)
given a set of vectors, return an orthogonal (C^T C == 1) set spanning the same space (notice,...
subroutine, public make_basis_sm(vmatrix, ncol, matrix_s)
returns an S-orthonormal basis v (v^T S v ==1)
Definition and initialisation of the mo data type.
subroutine, public set_mo_set(mo_set, maxocc, homo, lfomo, nao, nelectron, n_el_f, nmo, eigenvalues, occupation_numbers, uniform_occupation, kts, mu, flexible_electron_count)
Set the components of a MO set data structure.
subroutine, public allocate_mo_set(mo_set, nao, nmo, nelectron, n_el_f, maxocc, flexible_electron_count)
Allocates a mo set and partially initializes it (nao,nmo,nelectron, and flexible_electron_count are v...
subroutine, public deallocate_mo_set(mo_set)
Deallocate a wavefunction data structure.
subroutine, public transfer_rs2pw(rs, pw)
...
subroutine, public rs_grid_zero(rs)
Initialize grid to zero.
All kind of helpful little routines.
Provides all information about an atomic kind.
Type defining parameters related to the simulation cell.
represent a pointer to a 1d array
represent a pointer to a 1d array
represent a pointer to a 2d array
keeps the information about the structure of 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
quantities needed for a Hirshfeld based partitioning of real space
Container for constraint settings to check consistency of force_evals.
Main mixed CDFT control type.
represent a list of objects
contained for different pw related things
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.