116#include "./base/base_uses.f90"
122 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'mixed_cdft_methods'
123 LOGICAL,
PARAMETER,
PRIVATE :: debug_this_module = .false.
126 INTEGER :: imap(6) = 0
127 INTEGER,
DIMENSION(:), &
128 POINTER :: iv => null()
129 REAL(KIND=
dp),
POINTER, &
130 DIMENSION(:, :, :) :: r3 => null()
131 REAL(KIND=
dp),
POINTER, &
132 DIMENSION(:, :, :, :) :: r4 => null()
133 END TYPE buffers_idx_irr
136 LOGICAL,
POINTER,
DIMENSION(:) :: bv => null()
137 INTEGER,
POINTER,
DIMENSION(:) :: iv => null()
155 LOGICAL,
INTENT(IN) :: calculate_forces
157 CHARACTER(len=*),
PARAMETER :: routinen =
'mixed_cdft_init'
159 INTEGER :: et_freq, handle, iforce_eval, iounit, &
160 mixing_type, nforce_eval
161 LOGICAL :: explicit, is_parallel, is_qmmm
170 md_section, mixed_section, &
171 print_section, root_section
173 NULLIFY (subsys_mix, force_env_qs, force_env_section, print_section, &
174 root_section, mixed_section, md_section, mixed_env, mixed_cdft, &
177 NULLIFY (settings%grid_span, settings%npts, settings%cutoff, settings%rel_cutoff, &
178 settings%spherical, settings%rs_dims, settings%odd, settings%atoms, &
179 settings%coeffs, settings%si, settings%sr, &
180 settings%cutoffs, settings%radii)
184 cpassert(
ASSOCIATED(force_env))
185 nforce_eval =
SIZE(force_env%sub_force_env)
186 CALL timeset(routinen, handle)
187 CALL force_env_get(force_env=force_env, force_env_section=force_env_section)
188 mixed_env => force_env%mixed_env
194 IF (mixing_type ==
mix_cdft .AND. .NOT.
ASSOCIATED(mixed_env%cdft_control))
THEN
195 mixed_env%do_mixed_cdft = .true.
196 IF (mixed_env%do_mixed_cdft)
THEN
198 IF (nforce_eval < 2)
THEN
199 CALL cp_abort(__location__, &
200 "Mixed CDFT calculation requires at least 2 force_evals.")
206 cpabort(
"Please disable section &MAPPING for mixed CDFT calculations")
209 IF (et_freq < 0)
THEN
210 mixed_env%do_mixed_et = .false.
212 mixed_env%do_mixed_et = .true.
213 IF (et_freq == 0)
THEN
214 mixed_env%et_freq = 1
216 mixed_env%et_freq = et_freq
221 DO iforce_eval = 1, nforce_eval
222 IF (.NOT.
ASSOCIATED(force_env%sub_force_env(iforce_eval)%force_env)) cycle
223 SELECT CASE (force_env%sub_force_env(iforce_eval)%force_env%in_use)
225 force_env_qs => force_env%sub_force_env(iforce_eval)%force_env
229 force_env_qs => force_env%sub_force_env(iforce_eval)%force_env
231 cpabort(
"No force mixing allowed for mixed CDFT QM/MM")
233 CALL cp_abort(__location__, &
234 "Only use_qs_force and use_qmmm are "// &
235 "supported for mixed_cdft_init")
237 cpassert(
ASSOCIATED(force_env_qs))
240 IF (.NOT. is_qmmm)
THEN
244 particles=particles_mix)
246 CALL get_qs_env(force_env_qs%qmmm_env%qs_env, &
247 cp_subsys=subsys_mix)
249 particles=particles_mix)
252 ALLOCATE (mixed_cdft)
254 mixed_cdft%first_iteration = .true.
256 IF (mixed_env%ngroups == 1)
THEN
259 ELSE IF (mixed_env%ngroups == 2)
THEN
261 IF (is_parallel)
THEN
264 IF (.NOT. nforce_eval == 2)
THEN
265 CALL cp_abort(__location__, &
266 "Parallel mode mixed CDFT calculation supports only 2 force_evals.")
276 mixed_env%do_mixed_qmmm_cdft = is_qmmm
279 mixed_cdft%dlb = mixed_cdft%dlb .AND. calculate_forces
281 IF (mixed_cdft%dlb)
THEN
282 ALLOCATE (mixed_cdft%dlb_control)
283 NULLIFY (mixed_cdft%dlb_control%weight, mixed_cdft%dlb_control%gradients, &
284 mixed_cdft%dlb_control%cavity, mixed_cdft%dlb_control%target_list, &
285 mixed_cdft%dlb_control%bo, mixed_cdft%dlb_control%expected_work, &
286 mixed_cdft%dlb_control%prediction_error, mixed_cdft%dlb_control%sendbuff, &
287 mixed_cdft%dlb_control%recvbuff, mixed_cdft%dlb_control%recv_work_repl, &
288 mixed_cdft%dlb_control%recv_info)
290 r_val=mixed_cdft%dlb_control%load_scale)
292 r_val=mixed_cdft%dlb_control%very_overloaded)
294 i_val=mixed_cdft%dlb_control%more_work)
297 mixed_cdft%calculate_metric = .false.
298 mixed_cdft%wfn_overlap_method = .false.
299 mixed_cdft%use_lowdin = .false.
300 mixed_cdft%do_ci = .false.
301 mixed_cdft%nonortho_coupling = .false.
302 mixed_cdft%identical_constraints = .true.
303 mixed_cdft%block_diagonalize = .false.
304 IF (mixed_env%do_mixed_et)
THEN
306 l_val=mixed_cdft%calculate_metric)
308 l_val=mixed_cdft%wfn_overlap_method)
310 l_val=mixed_cdft%use_lowdin)
312 l_val=mixed_cdft%do_ci)
314 l_val=mixed_cdft%nonortho_coupling)
316 l_val=mixed_cdft%block_diagonalize)
320 IF (mixed_cdft%eps_svd < 0.0_dp .OR. mixed_cdft%eps_svd > 1.0_dp)
THEN
321 cpabort(
"Illegal value for EPS_SVD. Value must be between 0.0 and 1.0.")
328 mixed_cdft%sim_step = mixed_cdft%sim_step - 1
332 settings, natom=
SIZE(particles_mix%els))
340 WRITE (iounit, fmt=
"(T2,A,T71)") &
341 "MIXED_CDFT| Activating mixed CDFT calculation"
342 WRITE (iounit, fmt=
"(T2,A,T71,I10)") &
343 "MIXED_CDFT| Number of CDFT states: ", nforce_eval
344 SELECT CASE (mixed_cdft%run_type)
346 WRITE (iounit, fmt=
"(T2,A,T71)") &
347 "MIXED_CDFT| CDFT states calculation mode: parallel with build"
348 WRITE (iounit, fmt=
"(T2,A,T71)") &
349 "MIXED_CDFT| Becke constraint is first built using all available processors"
350 WRITE (iounit, fmt=
"(T2,A,T71)") &
351 " and then copied to both states with their own processor groups"
353 WRITE (iounit, fmt=
"(T2,A,T71)") &
354 "MIXED_CDFT| CDFT states calculation mode: serial"
355 IF (mixed_cdft%identical_constraints)
THEN
356 WRITE (iounit, fmt=
"(T2,A,T71)") &
357 "MIXED_CDFT| The constraints are built before the SCF procedure of the first"
358 WRITE (iounit, fmt=
"(T2,A,T71)") &
359 " CDFT state and subsequently copied to the other states"
361 WRITE (iounit, fmt=
"(T2,A,T71)") &
362 "MIXED_CDFT| The constraints are separately built for all CDFT states"
365 WRITE (iounit, fmt=
"(T2,A,T71)") &
366 "MIXED_CDFT| CDFT states calculation mode: parallel without build"
367 WRITE (iounit, fmt=
"(T2,A,T71)") &
368 "MIXED_CDFT| The constraints are separately built for all CDFT states"
370 cpabort(
"Unknown mixed CDFT run type.")
372 WRITE (iounit, fmt=
"(T2,A,T71,L10)") &
373 "MIXED_CDFT| Calculating electronic coupling between states: ", mixed_env%do_mixed_et
374 WRITE (iounit, fmt=
"(T2,A,T71,L10)") &
375 "MIXED_CDFT| Calculating electronic coupling reliability metric: ", mixed_cdft%calculate_metric
376 WRITE (iounit, fmt=
"(T2,A,T71,L10)") &
377 "MIXED_CDFT| Configuration interaction (CDFT-CI) was requested: ", mixed_cdft%do_ci
378 WRITE (iounit, fmt=
"(T2,A,T71,L10)") &
379 "MIXED_CDFT| Block diagonalizing the mixed CDFT Hamiltonian: ", mixed_cdft%block_diagonalize
381 WRITE (iounit, fmt=
"(T2,A,T71,L10)") &
382 "MIXED_CDFT| Dynamic load balancing enabled: ", mixed_cdft%dlb
383 IF (mixed_cdft%dlb)
THEN
384 WRITE (iounit, fmt=
"(T2,A,T71)")
"MIXED_CDFT| Dynamic load balancing parameters:"
385 WRITE (iounit, fmt=
"(T2,A,T71,F10.2)") &
386 "MIXED_CDFT| load_scale:", mixed_cdft%dlb_control%load_scale
387 WRITE (iounit, fmt=
"(T2,A,T71,F10.2)") &
388 "MIXED_CDFT| very_overloaded:", mixed_cdft%dlb_control%very_overloaded
389 WRITE (iounit, fmt=
"(T2,A,T71,I10)") &
390 "MIXED_CDFT| more_work:", mixed_cdft%dlb_control%more_work
393 IF (mixed_env%do_mixed_et)
THEN
394 IF (mixed_cdft%eps_svd == 0.0_dp)
THEN
395 WRITE (iounit, fmt=
"(T2,A,T71)")
"MIXED_CDFT| Matrix inversions calculated with LU decomposition."
397 WRITE (iounit, fmt=
"(T2,A,T71)")
"MIXED_CDFT| Matrix inversions calculated with SVD decomposition."
398 WRITE (iounit, fmt=
"(T2,A,T71,ES10.2)")
"MIXED_CDFT| EPS_SVD:", mixed_cdft%eps_svd
406 "MIXED%MIXED_CDFT%PRINT%PROGRAM_RUN_INFO")
407 CALL timestop(handle)
421 LOGICAL,
INTENT(IN) :: calculate_forces
422 INTEGER,
INTENT(IN),
OPTIONAL :: iforce_eval
427 cpassert(
ASSOCIATED(force_env))
428 CALL get_mixed_env(force_env%mixed_env, cdft_control=mixed_cdft)
429 cpassert(
ASSOCIATED(mixed_cdft))
430 IF (.NOT.
PRESENT(iforce_eval))
THEN
431 SELECT CASE (mixed_cdft%run_type)
433 CALL mixed_cdft_build_weight_parallel(force_env, calculate_forces)
435 CALL mixed_cdft_set_flags(force_env)
440 SELECT CASE (mixed_cdft%run_type)
442 CALL mixed_cdft_transfer_weight(force_env, calculate_forces, iforce_eval)
457 SUBROUTINE mixed_cdft_build_weight_parallel(force_env, calculate_forces)
459 LOGICAL,
INTENT(IN) :: calculate_forces
461 CHARACTER(len=*),
PARAMETER :: routinen =
'mixed_cdft_build_weight_parallel'
463 INTEGER :: handle, handle2, i, iforce_eval, ind, index(6), iounit, j, lb_min, &
464 my_special_work, natom, nforce_eval, recv_offset, ub_max
465 INTEGER,
DIMENSION(2, 3) :: bo
466 INTEGER,
DIMENSION(:),
POINTER :: lb, sendbuffer_i, ub
467 REAL(kind=
dp) :: t1, t2
468 TYPE(buffers_idx_irr),
DIMENSION(:),
POINTER :: recvbuffer
479 TYPE(
pw_pool_type),
POINTER :: auxbas_pw_pool, mixed_auxbas_pw_pool
483 NULLIFY (subsys_mix, force_env_qs, particles_mix, force_env_section, print_section, &
484 mixed_env, mixed_cdft, pw_env, auxbas_pw_pool, mixed_auxbas_pw_pool, &
485 qs_env, dft_control, sendbuffer_i, lb, ub, req_total, recvbuffer, &
486 cdft_control, cdft_control_target)
489 cpassert(
ASSOCIATED(force_env))
490 nforce_eval =
SIZE(force_env%sub_force_env)
491 CALL timeset(routinen, handle)
496 force_env_section=force_env_section)
498 particles=particles_mix)
499 DO iforce_eval = 1, nforce_eval
500 IF (.NOT.
ASSOCIATED(force_env%sub_force_env(iforce_eval)%force_env)) cycle
501 SELECT CASE (force_env%sub_force_env(iforce_eval)%force_env%in_use)
503 force_env_qs => force_env%sub_force_env(iforce_eval)%force_env
505 force_env_qs => force_env%sub_force_env(iforce_eval)%force_env
507 CALL cp_abort(__location__, &
508 "Only use_qs_force and use_qmmm are "// &
509 "supported for mixed_cdft_build_weight_parallel")
512 IF (.NOT. force_env%mixed_env%do_mixed_qmmm_cdft)
THEN
517 particles=particles_mix)
519 qs_env => force_env_qs%qmmm_env%qs_env
522 particles=particles_mix)
524 mixed_env => force_env%mixed_env
528 cpassert(
ASSOCIATED(mixed_cdft))
529 cdft_control => mixed_cdft%cdft_control
530 cpassert(
ASSOCIATED(cdft_control))
532 CALL pw_env_get(pw_env=mixed_cdft%pw_env, auxbas_pw_pool=mixed_auxbas_pw_pool)
533 natom =
SIZE(particles_mix%els)
534 CALL mixed_becke_constraint(force_env, calculate_forces)
536 mixed_cdft%sim_step = mixed_cdft%sim_step + 1
537 CALL get_qs_env(qs_env, pw_env=pw_env, dft_control=dft_control)
538 cdft_control_target => dft_control%qs_control%cdft_control
539 cpassert(dft_control%qs_control%cdft)
540 cpassert(
ASSOCIATED(cdft_control_target))
541 CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool)
542 bo = auxbas_pw_pool%pw_grid%bounds_local
544 IF (mixed_cdft%is_special)
THEN
549 ALLOCATE (recvbuffer(
SIZE(mixed_cdft%source_list)))
550 ALLOCATE (req_total(my_special_work*
SIZE(mixed_cdft%dest_list) +
SIZE(mixed_cdft%source_list)))
551 ALLOCATE (lb(
SIZE(mixed_cdft%source_list)), ub(
SIZE(mixed_cdft%source_list)))
552 IF (cdft_control%becke_control%cavity_confine)
THEN
554 ALLOCATE (sendbuffer_i(2))
555 sendbuffer_i = cdft_control%becke_control%confine_bounds
556 DO i = 1,
SIZE(mixed_cdft%source_list)
557 ALLOCATE (recvbuffer(i)%iv(2))
558 CALL force_env%para_env%irecv(msgout=recvbuffer(i)%iv, source=mixed_cdft%source_list(i), &
559 request=req_total(i))
561 DO i = 1, my_special_work
562 DO j = 1,
SIZE(mixed_cdft%dest_list)
563 ind = j + (i - 1)*
SIZE(mixed_cdft%dest_list) +
SIZE(mixed_cdft%source_list)
564 CALL force_env%para_env%isend(msgin=sendbuffer_i, &
565 dest=mixed_cdft%dest_list(j) + (i - 1)*force_env%para_env%num_pe/2, &
566 request=req_total(ind))
571 DEALLOCATE (sendbuffer_i)
574 DO i = 1,
SIZE(mixed_cdft%source_list)
575 lb(i) = recvbuffer(i)%iv(1)
576 ub(i) = recvbuffer(i)%iv(2)
577 IF (lb(i) < lb_min) lb_min = lb(i)
578 IF (ub(i) > ub_max) ub_max = ub(i)
579 DEALLOCATE (recvbuffer(i)%iv)
582 IF (mixed_cdft%dlb)
THEN
583 IF (any(mixed_cdft%dlb_control%recv_work_repl))
THEN
584 DO j = 1,
SIZE(mixed_cdft%dlb_control%recv_work_repl)
585 IF (mixed_cdft%dlb_control%recv_work_repl(j))
THEN
586 DO i = 1,
SIZE(mixed_cdft%dlb_control%recvbuff(j)%buffs)
587 IF (lbound(mixed_cdft%dlb_control%recvbuff(j)%buffs(i)%weight, 3) &
588 < lb_min) lb_min = lbound(mixed_cdft%dlb_control%recvbuff(j)%buffs(i)%weight, 3)
589 IF (ubound(mixed_cdft%dlb_control%recvbuff(j)%buffs(i)%weight, 3) &
590 > ub_max) ub_max = ubound(mixed_cdft%dlb_control%recvbuff(j)%buffs(i)%weight, 3)
604 CALL timeset(routinen//
"_comm", handle2)
605 DO j = 1,
SIZE(recvbuffer)
607 IF (mixed_cdft%is_special)
THEN
608 recvbuffer(j)%imap = [mixed_cdft%source_list_bo(1, j), mixed_cdft%source_list_bo(2, j), &
609 mixed_cdft%source_list_bo(3, j), mixed_cdft%source_list_bo(4, j), &
611 ELSE IF (mixed_cdft%is_pencil)
THEN
612 recvbuffer(j)%imap = [bo(1, 1), bo(2, 1), mixed_cdft%recv_bo(ind), mixed_cdft%recv_bo(ind + 1), lb(j), ub(j)]
614 recvbuffer(j)%imap = [mixed_cdft%recv_bo(ind), mixed_cdft%recv_bo(ind + 1), bo(1, 2), bo(2, 2), lb(j), ub(j)]
617 IF (mixed_cdft%dlb .AND. .NOT. mixed_cdft%is_special)
THEN
618 IF (mixed_cdft%dlb_control%recv_work_repl(1) .OR. mixed_cdft%dlb_control%recv_work_repl(2))
THEN
621 IF (mixed_cdft%dlb_control%recv_work_repl(j))
THEN
622 recv_offset = sum(mixed_cdft%dlb_control%recv_info(j)%target_list(2, :))
624 IF (mixed_cdft%is_pencil)
THEN
625 recvbuffer(j)%imap(1) = recvbuffer(j)%imap(1) + recv_offset
627 recvbuffer(j)%imap(3) = recvbuffer(j)%imap(3) + recv_offset
634 DO j = 1,
SIZE(mixed_cdft%source_list)
635 ALLOCATE (recvbuffer(j)%r3(recvbuffer(j)%imap(1):recvbuffer(j)%imap(2), &
636 recvbuffer(j)%imap(3):recvbuffer(j)%imap(4), &
637 recvbuffer(j)%imap(5):recvbuffer(j)%imap(6)))
639 CALL force_env%para_env%irecv(msgout=recvbuffer(j)%r3, source=mixed_cdft%source_list(j), &
640 request=req_total(j))
642 DO i = 1, my_special_work
643 DO j = 1,
SIZE(mixed_cdft%dest_list)
644 ind = j + (i - 1)*
SIZE(mixed_cdft%dest_list) +
SIZE(mixed_cdft%source_list)
645 IF (mixed_cdft%is_special)
THEN
646 CALL force_env%para_env%isend(msgin=mixed_cdft%sendbuff(j)%weight, &
647 dest=mixed_cdft%dest_list(j) + (i - 1)*force_env%para_env%num_pe/2, &
648 request=req_total(ind))
650 CALL force_env%para_env%isend(msgin=mixed_cdft%weight, dest=mixed_cdft%dest_list(j), &
651 request=req_total(ind))
656 IF (mixed_cdft%is_special)
THEN
657 DO j = 1,
SIZE(mixed_cdft%dest_list)
658 DEALLOCATE (mixed_cdft%sendbuff(j)%weight)
661 DEALLOCATE (mixed_cdft%weight)
665 ALLOCATE (cdft_control_target%group(1)%weight)
666 CALL auxbas_pw_pool%create_pw(cdft_control_target%group(1)%weight)
667 CALL pw_zero(cdft_control_target%group(1)%weight)
669 DO j = 1,
SIZE(mixed_cdft%source_list)
670 cdft_control_target%group(1)%weight%array(recvbuffer(j)%imap(1):recvbuffer(j)%imap(2), &
671 recvbuffer(j)%imap(3):recvbuffer(j)%imap(4), &
672 recvbuffer(j)%imap(5):recvbuffer(j)%imap(6)) = recvbuffer(j)%r3
675 IF (mixed_cdft%dlb)
THEN
676 IF (any(mixed_cdft%dlb_control%recv_work_repl))
THEN
677 DO j = 1,
SIZE(mixed_cdft%dlb_control%recv_work_repl)
678 IF (mixed_cdft%dlb_control%recv_work_repl(j))
THEN
679 DO i = 1,
SIZE(mixed_cdft%dlb_control%recvbuff(j)%buffs)
680 index = [lbound(mixed_cdft%dlb_control%recvbuff(j)%buffs(i)%weight, 1), &
681 ubound(mixed_cdft%dlb_control%recvbuff(j)%buffs(i)%weight, 1), &
682 lbound(mixed_cdft%dlb_control%recvbuff(j)%buffs(i)%weight, 2), &
683 ubound(mixed_cdft%dlb_control%recvbuff(j)%buffs(i)%weight, 2), &
684 lbound(mixed_cdft%dlb_control%recvbuff(j)%buffs(i)%weight, 3), &
685 ubound(mixed_cdft%dlb_control%recvbuff(j)%buffs(i)%weight, 3)]
686 cdft_control_target%group(1)%weight%array(index(1):index(2), &
688 index(5):index(6)) = &
689 mixed_cdft%dlb_control%recvbuff(j)%buffs(i)%weight
690 DEALLOCATE (mixed_cdft%dlb_control%recvbuff(j)%buffs(i)%weight)
697 IF (cdft_control%becke_control%cavity_confine)
THEN
698 DO j = 1,
SIZE(mixed_cdft%source_list)
699 CALL force_env%para_env%irecv(msgout=recvbuffer(j)%r3, source=mixed_cdft%source_list(j), &
700 request=req_total(j))
702 DO i = 1, my_special_work
703 DO j = 1,
SIZE(mixed_cdft%dest_list)
704 ind = j + (i - 1)*
SIZE(mixed_cdft%dest_list) +
SIZE(mixed_cdft%source_list)
705 IF (mixed_cdft%is_special)
THEN
706 CALL force_env%para_env%isend(msgin=mixed_cdft%sendbuff(j)%cavity, &
707 dest=mixed_cdft%dest_list(j) + (i - 1)*force_env%para_env%num_pe/2, &
708 request=req_total(ind))
710 CALL force_env%para_env%isend(msgin=mixed_cdft%cavity, dest=mixed_cdft%dest_list(j), &
711 request=req_total(ind))
716 IF (mixed_cdft%is_special)
THEN
717 DO j = 1,
SIZE(mixed_cdft%dest_list)
718 DEALLOCATE (mixed_cdft%sendbuff(j)%cavity)
721 DEALLOCATE (mixed_cdft%cavity)
724 ALLOCATE (cdft_control_target%becke_control%cavity_mat(bo(1, 1):bo(2, 1), &
727 cdft_control_target%becke_control%cavity_mat = 0.0_dp
729 DO j = 1,
SIZE(mixed_cdft%source_list)
730 cdft_control_target%becke_control%cavity_mat(recvbuffer(j)%imap(1):recvbuffer(j)%imap(2), &
731 recvbuffer(j)%imap(3):recvbuffer(j)%imap(4), &
732 recvbuffer(j)%imap(5):recvbuffer(j)%imap(6)) = recvbuffer(j)%r3
734 IF (mixed_cdft%dlb)
THEN
735 IF (any(mixed_cdft%dlb_control%recv_work_repl))
THEN
736 DO j = 1,
SIZE(mixed_cdft%dlb_control%recv_work_repl)
737 IF (mixed_cdft%dlb_control%recv_work_repl(j))
THEN
738 DO i = 1,
SIZE(mixed_cdft%dlb_control%recvbuff(j)%buffs)
739 index = [lbound(mixed_cdft%dlb_control%recvbuff(j)%buffs(i)%cavity, 1), &
740 ubound(mixed_cdft%dlb_control%recvbuff(j)%buffs(i)%cavity, 1), &
741 lbound(mixed_cdft%dlb_control%recvbuff(j)%buffs(i)%cavity, 2), &
742 ubound(mixed_cdft%dlb_control%recvbuff(j)%buffs(i)%cavity, 2), &
743 lbound(mixed_cdft%dlb_control%recvbuff(j)%buffs(i)%cavity, 3), &
744 ubound(mixed_cdft%dlb_control%recvbuff(j)%buffs(i)%cavity, 3)]
745 cdft_control_target%becke_control%cavity_mat(index(1):index(2), &
747 index(5):index(6)) = &
748 mixed_cdft%dlb_control%recvbuff(j)%buffs(i)%cavity
749 DEALLOCATE (mixed_cdft%dlb_control%recvbuff(j)%buffs(i)%cavity)
756 DO j = 1,
SIZE(mixed_cdft%source_list)
757 DEALLOCATE (recvbuffer(j)%r3)
759 IF (calculate_forces)
THEN
761 DO j = 1,
SIZE(mixed_cdft%source_list)
762 ALLOCATE (recvbuffer(j)%r4(3*natom, recvbuffer(j)%imap(1):recvbuffer(j)%imap(2), &
763 recvbuffer(j)%imap(3):recvbuffer(j)%imap(4), &
764 recvbuffer(j)%imap(5):recvbuffer(j)%imap(6)))
765 CALL force_env%para_env%irecv(msgout=recvbuffer(j)%r4, source=mixed_cdft%source_list(j), &
766 request=req_total(j))
768 DO i = 1, my_special_work
769 DO j = 1,
SIZE(mixed_cdft%dest_list)
770 ind = j + (i - 1)*
SIZE(mixed_cdft%dest_list) +
SIZE(mixed_cdft%source_list)
771 IF (mixed_cdft%is_special)
THEN
772 CALL force_env%para_env%isend(msgin=mixed_cdft%sendbuff(j)%gradients, &
773 dest=mixed_cdft%dest_list(j) + (i - 1)*force_env%para_env%num_pe/2, &
774 request=req_total(ind))
776 CALL force_env%para_env%isend(msgin=cdft_control%group(1)%gradients, dest=mixed_cdft%dest_list(j), &
777 request=req_total(ind))
782 IF (mixed_cdft%is_special)
THEN
783 DO j = 1,
SIZE(mixed_cdft%dest_list)
784 DEALLOCATE (mixed_cdft%sendbuff(j)%gradients)
786 DEALLOCATE (mixed_cdft%sendbuff)
788 DEALLOCATE (cdft_control%group(1)%gradients)
790 ALLOCATE (cdft_control_target%group(1)%gradients(3*natom, bo(1, 1):bo(2, 1), &
791 bo(1, 2):bo(2, 2), lb_min:ub_max))
792 DO j = 1,
SIZE(mixed_cdft%source_list)
793 cdft_control_target%group(1)%gradients(:, recvbuffer(j)%imap(1):recvbuffer(j)%imap(2), &
794 recvbuffer(j)%imap(3):recvbuffer(j)%imap(4), &
795 recvbuffer(j)%imap(5):recvbuffer(j)%imap(6)) = recvbuffer(j)%r4
796 DEALLOCATE (recvbuffer(j)%r4)
798 IF (mixed_cdft%dlb)
THEN
799 IF (any(mixed_cdft%dlb_control%recv_work_repl))
THEN
800 DO j = 1,
SIZE(mixed_cdft%dlb_control%recv_work_repl)
801 IF (mixed_cdft%dlb_control%recv_work_repl(j))
THEN
802 DO i = 1,
SIZE(mixed_cdft%dlb_control%recvbuff(j)%buffs)
803 index = [lbound(mixed_cdft%dlb_control%recvbuff(j)%buffs(i)%gradients, 2), &
804 ubound(mixed_cdft%dlb_control%recvbuff(j)%buffs(i)%gradients, 2), &
805 lbound(mixed_cdft%dlb_control%recvbuff(j)%buffs(i)%gradients, 3), &
806 ubound(mixed_cdft%dlb_control%recvbuff(j)%buffs(i)%gradients, 3), &
807 lbound(mixed_cdft%dlb_control%recvbuff(j)%buffs(i)%gradients, 4), &
808 ubound(mixed_cdft%dlb_control%recvbuff(j)%buffs(i)%gradients, 4)]
809 cdft_control_target%group(1)%gradients(:, index(1):index(2), &
811 index(5):index(6)) = &
812 mixed_cdft%dlb_control%recvbuff(j)%buffs(i)%gradients
813 DEALLOCATE (mixed_cdft%dlb_control%recvbuff(j)%buffs(i)%gradients)
821 IF (mixed_cdft%dlb)
THEN
822 IF (any(mixed_cdft%dlb_control%recv_work_repl))
THEN
823 DO j = 1,
SIZE(mixed_cdft%dlb_control%recv_work_repl)
824 IF (mixed_cdft%dlb_control%recv_work_repl(j))
THEN
825 IF (
ASSOCIATED(mixed_cdft%dlb_control%recv_info(j)%target_list))
THEN
826 DEALLOCATE (mixed_cdft%dlb_control%recv_info(j)%target_list)
828 DEALLOCATE (mixed_cdft%dlb_control%recvbuff(j)%buffs)
831 DEALLOCATE (mixed_cdft%dlb_control%recv_info, mixed_cdft%dlb_control%recvbuff)
833 IF (
ASSOCIATED(mixed_cdft%dlb_control%target_list))
THEN
834 DEALLOCATE (mixed_cdft%dlb_control%target_list)
836 DEALLOCATE (mixed_cdft%dlb_control%recv_work_repl)
838 DEALLOCATE (recvbuffer)
839 DEALLOCATE (req_total)
842 CALL timestop(handle2)
844 cdft_control_target%external_control = .true.
845 cdft_control_target%need_pot = .false.
846 cdft_control_target%transfer_pot = .false.
848 IF (calculate_forces)
THEN
849 cdft_control_target%becke_control%confine_bounds(2) = ub_max
850 cdft_control_target%becke_control%confine_bounds(1) = lb_min
852 CALL pw_scale(cdft_control_target%group(1)%weight, &
853 cdft_control_target%group(1)%weight%pw_grid%dvol)
855 IF (mixed_env%do_mixed_et)
THEN
856 IF (
modulo(mixed_cdft%sim_step, mixed_env%et_freq) == 0)
THEN
857 dft_control%qs_control%cdft_control%do_et = .true.
858 dft_control%qs_control%cdft_control%calculate_metric = mixed_cdft%calculate_metric
860 dft_control%qs_control%cdft_control%do_et = .false.
861 dft_control%qs_control%cdft_control%calculate_metric = .false.
866 WRITE (iounit,
'(A)')
' '
867 WRITE (iounit,
'(T2,A,F6.1,A)')
'MIXED_CDFT| Becke constraint built in ', t2 - t1,
' seconds'
868 WRITE (iounit,
'(A)')
' '
871 "MIXED%MIXED_CDFT%PRINT%PROGRAM_RUN_INFO")
872 CALL timestop(handle)
874 END SUBROUTINE mixed_cdft_build_weight_parallel
884 SUBROUTINE mixed_cdft_transfer_weight(force_env, calculate_forces, iforce_eval)
886 LOGICAL,
INTENT(IN) :: calculate_forces
887 INTEGER,
INTENT(IN) :: iforce_eval
889 CHARACTER(len=*),
PARAMETER :: routinen =
'mixed_cdft_transfer_weight'
891 INTEGER :: bounds_of(8), handle, iatom, igroup, &
892 jforce_eval, nforce_eval
893 LOGICAL,
SAVE :: first_call = .true.
896 TYPE(
force_env_type),
POINTER :: force_env_qs_source, force_env_qs_target
899 TYPE(
pw_env_type),
POINTER :: pw_env_source, pw_env_target
901 auxbas_pw_pool_target
904 NULLIFY (mixed_cdft, dft_control_source, dft_control_target, force_env_qs_source, &
905 force_env_qs_target, pw_env_source, pw_env_target, auxbas_pw_pool_source, &
906 auxbas_pw_pool_target, qs_env_source, qs_env_target, mixed_env, &
907 cdft_control_source, cdft_control_target)
908 mixed_env => force_env%mixed_env
910 CALL timeset(routinen, handle)
911 IF (iforce_eval == 1)
THEN
914 jforce_eval = iforce_eval - 1
916 nforce_eval =
SIZE(force_env%sub_force_env)
917 SELECT CASE (force_env%sub_force_env(jforce_eval)%force_env%in_use)
919 force_env_qs_source => force_env%sub_force_env(jforce_eval)%force_env
920 force_env_qs_target => force_env%sub_force_env(iforce_eval)%force_env
922 CALL cp_abort(__location__, &
923 "Only use_qs_force and use_qmmm are "// &
924 "supported for mixed_cdft_transfer_weight")
926 IF (.NOT. force_env%mixed_env%do_mixed_qmmm_cdft)
THEN
928 qs_env=qs_env_source)
930 qs_env=qs_env_target)
932 qs_env_source => force_env_qs_source%qmmm_env%qs_env
933 qs_env_target => force_env_qs_target%qmmm_env%qs_env
935 IF (iforce_eval == 1)
THEN
938 CALL get_qs_env(qs_env_source, dft_control=dft_control_source)
939 cdft_control_source => dft_control_source%qs_control%cdft_control
940 cdft_control_source%external_control = .false.
941 cdft_control_source%need_pot = .true.
942 IF (mixed_cdft%identical_constraints)
THEN
943 cdft_control_source%transfer_pot = .true.
945 cdft_control_source%transfer_pot = .false.
947 mixed_cdft%sim_step = mixed_cdft%sim_step + 1
950 CALL get_qs_env(qs_env_source, dft_control=dft_control_source, &
951 pw_env=pw_env_source)
952 CALL pw_env_get(pw_env_source, auxbas_pw_pool=auxbas_pw_pool_source)
953 cdft_control_source => dft_control_source%qs_control%cdft_control
954 CALL get_qs_env(qs_env_target, dft_control=dft_control_target, &
955 pw_env=pw_env_target)
956 CALL pw_env_get(pw_env_target, auxbas_pw_pool=auxbas_pw_pool_target)
957 cdft_control_target => dft_control_target%qs_control%cdft_control
959 IF (mixed_cdft%identical_constraints)
THEN
961 DO igroup = 1,
SIZE(cdft_control_target%group)
962 ALLOCATE (cdft_control_target%group(igroup)%weight)
963 CALL auxbas_pw_pool_target%create_pw(cdft_control_target%group(igroup)%weight)
965 CALL pw_copy(cdft_control_source%group(igroup)%weight, cdft_control_target%group(igroup)%weight)
966 CALL auxbas_pw_pool_source%give_back_pw(cdft_control_source%group(igroup)%weight)
967 DEALLOCATE (cdft_control_source%group(igroup)%weight)
971 IF (cdft_control_source%becke_control%cavity_confine)
THEN
972 CALL auxbas_pw_pool_target%create_pw(cdft_control_target%becke_control%cavity)
973 CALL pw_copy(cdft_control_source%becke_control%cavity, cdft_control_target%becke_control%cavity)
974 CALL auxbas_pw_pool_source%give_back_pw(cdft_control_source%becke_control%cavity)
978 IF (calculate_forces)
THEN
979 DO igroup = 1,
SIZE(cdft_control_source%group)
980 bounds_of = [lbound(cdft_control_source%group(igroup)%gradients, 1), &
981 ubound(cdft_control_source%group(igroup)%gradients, 1), &
982 lbound(cdft_control_source%group(igroup)%gradients, 2), &
983 ubound(cdft_control_source%group(igroup)%gradients, 2), &
984 lbound(cdft_control_source%group(igroup)%gradients, 3), &
985 ubound(cdft_control_source%group(igroup)%gradients, 3), &
986 lbound(cdft_control_source%group(igroup)%gradients, 4), &
987 ubound(cdft_control_source%group(igroup)%gradients, 4)]
988 ALLOCATE (cdft_control_target%group(igroup)% &
989 gradients(bounds_of(1):bounds_of(2), bounds_of(3):bounds_of(4), &
990 bounds_of(5):bounds_of(6), bounds_of(7):bounds_of(8)))
991 cdft_control_target%group(igroup)%gradients = cdft_control_source%group(igroup)%gradients
992 DEALLOCATE (cdft_control_source%group(igroup)%gradients)
996 IF (cdft_control_source%atomic_charges)
THEN
997 IF (.NOT.
ASSOCIATED(cdft_control_target%charge))
THEN
998 ALLOCATE (cdft_control_target%charge(cdft_control_target%natoms))
1000 DO iatom = 1, cdft_control_target%natoms
1001 CALL auxbas_pw_pool_target%create_pw(cdft_control_target%charge(iatom))
1002 CALL pw_copy(cdft_control_source%charge(iatom), cdft_control_target%charge(iatom))
1003 CALL auxbas_pw_pool_source%give_back_pw(cdft_control_source%charge(iatom))
1007 cdft_control_target%external_control = .false.
1008 cdft_control_target%need_pot = .false.
1010 IF (iforce_eval == nforce_eval)
THEN
1011 cdft_control_target%transfer_pot = .false.
1013 cdft_control_target%transfer_pot = .true.
1015 cdft_control_target%first_iteration = .false.
1018 cdft_control_target%external_control = .false.
1019 cdft_control_target%need_pot = .true.
1020 cdft_control_target%transfer_pot = .false.
1021 IF (first_call)
THEN
1022 cdft_control_target%first_iteration = .true.
1024 cdft_control_target%first_iteration = .false.
1029 IF (mixed_env%do_mixed_et)
THEN
1030 IF (
modulo(mixed_cdft%sim_step, mixed_env%et_freq) == 0)
THEN
1031 IF (iforce_eval == 1)
THEN
1032 cdft_control_source%do_et = .true.
1033 cdft_control_source%calculate_metric = mixed_cdft%calculate_metric
1035 cdft_control_target%do_et = .true.
1036 cdft_control_target%calculate_metric = mixed_cdft%calculate_metric
1039 IF (iforce_eval == 1)
THEN
1040 cdft_control_source%do_et = .false.
1041 cdft_control_source%calculate_metric = .false.
1043 cdft_control_target%do_et = .false.
1044 cdft_control_target%calculate_metric = .false.
1048 IF (iforce_eval == nforce_eval .AND. first_call) first_call = .false.
1049 CALL timestop(handle)
1051 END SUBROUTINE mixed_cdft_transfer_weight
1060 SUBROUTINE mixed_cdft_set_flags(force_env)
1063 CHARACTER(len=*),
PARAMETER :: routinen =
'mixed_cdft_set_flags'
1065 INTEGER :: handle, iforce_eval, nforce_eval
1066 LOGICAL,
SAVE :: first_call = .true.
1074 NULLIFY (mixed_cdft, dft_control, force_env_qs, qs_env, mixed_env, cdft_control)
1075 mixed_env => force_env%mixed_env
1077 CALL timeset(routinen, handle)
1078 nforce_eval =
SIZE(force_env%sub_force_env)
1079 DO iforce_eval = 1, nforce_eval
1080 IF (.NOT.
ASSOCIATED(force_env%sub_force_env(iforce_eval)%force_env)) cycle
1081 SELECT CASE (force_env%sub_force_env(iforce_eval)%force_env%in_use)
1083 force_env_qs => force_env%sub_force_env(iforce_eval)%force_env
1085 CALL cp_abort(__location__, &
1086 "Only use_qs_force and use_qmmm are "// &
1087 "supported for mixed_cdft_set_flags")
1089 IF (.NOT. force_env%mixed_env%do_mixed_qmmm_cdft)
THEN
1092 qs_env => force_env_qs%qmmm_env%qs_env
1096 CALL get_qs_env(qs_env, dft_control=dft_control)
1097 cdft_control => dft_control%qs_control%cdft_control
1098 cdft_control%external_control = .false.
1099 cdft_control%need_pot = .true.
1100 cdft_control%transfer_pot = .false.
1101 IF (first_call)
THEN
1102 cdft_control%first_iteration = .true.
1104 cdft_control%first_iteration = .false.
1107 IF (mixed_env%do_mixed_et)
THEN
1108 IF (
modulo(mixed_cdft%sim_step, mixed_env%et_freq) == 0)
THEN
1109 cdft_control%do_et = .true.
1110 cdft_control%calculate_metric = mixed_cdft%calculate_metric
1112 cdft_control%do_et = .false.
1113 cdft_control%calculate_metric = .false.
1117 mixed_cdft%sim_step = mixed_cdft%sim_step + 1
1118 IF (first_call) first_call = .false.
1119 CALL timestop(handle)
1121 END SUBROUTINE mixed_cdft_set_flags
1132 CHARACTER(len=*),
PARAMETER :: routinen =
'mixed_cdft_calculate_coupling'
1136 cpassert(
ASSOCIATED(force_env))
1137 CALL timeset(routinen, handle)
1143 CALL mixed_cdft_interaction_matrices(force_env)
1145 CALL mixed_cdft_calculate_coupling_low(force_env)
1149 CALL mixed_cdft_block_diag(force_env)
1151 CALL mixed_cdft_configuration_interaction(force_env)
1154 CALL timestop(handle)
1164 SUBROUTINE mixed_cdft_interaction_matrices(force_env)
1167 CHARACTER(len=*),
PARAMETER :: routinen =
'mixed_cdft_interaction_matrices'
1169 INTEGER :: check_ao(2), check_mo(2), handle, iforce_eval, ipermutation, ispin, istate, ivar, &
1170 j, jstate, k, moeigvalunit, mounit, nao, ncol_local, nforce_eval, nmo, npermutations, &
1171 nrow_local, nspins, nvar
1172 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: ncol_mo, nrow_mo
1173 INTEGER,
ALLOCATABLE,
DIMENSION(:, :) :: homo
1174 LOGICAL :: nelectron_mismatch, print_mo, &
1175 print_mo_eigval, should_scale, &
1177 REAL(kind=
dp) :: c(2), eps_occupied, nelectron_tot, &
1179 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: coupling_nonortho, eigenv, energy, sda
1180 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: h_mat, s_det, s_mat, strength, tmp_mat, &
1181 w_diagonal, wad, wda
1182 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :, :) :: a, b
1183 REAL(kind=
dp),
DIMENSION(:),
POINTER :: mo_eigval
1185 TYPE(
cp_fm_type) :: inverse_mat, tinverse, tmp2
1186 TYPE(
cp_fm_type),
ALLOCATABLE,
DIMENSION(:) :: mo_overlap
1187 TYPE(
cp_fm_type),
ALLOCATABLE,
DIMENSION(:, :, :) :: w_matrix_mo
1188 TYPE(
cp_fm_type),
DIMENSION(:, :),
POINTER :: mixed_mo_coeff
1190 TYPE(
dbcsr_p_type),
DIMENSION(:, :),
POINTER :: density_matrix, density_matrix_diff, &
1201 NULLIFY (force_env_section, print_section, mixed_cdft_section, &
1202 mixed_env, mixed_cdft, qs_env, dft_control, fm_struct_mo, &
1203 density_matrix_diff, mo_mo_fmstruct, &
1204 mixed_mo_coeff, mixed_matrix_s, &
1205 density_matrix, energy_qs, w_matrix, mo_eigval)
1207 cpassert(
ASSOCIATED(force_env))
1208 CALL timeset(routinen, handle)
1210 force_env_section=force_env_section)
1211 mixed_env => force_env%mixed_env
1212 nforce_eval =
SIZE(force_env%sub_force_env)
1221 print_mo_eigval = .true.
1222 moeigvalunit =
cp_print_key_unit_nr(logger, print_section, extension=
'.moOverlapEigval', on_file=.true.)
1224 print_mo_eigval = .false.
1228 cpassert(
ASSOCIATED(mixed_cdft))
1229 cpassert(
ASSOCIATED(mixed_cdft%matrix%mixed_mo_coeff))
1230 cpassert(
ASSOCIATED(mixed_cdft%matrix%w_matrix))
1231 cpassert(
ASSOCIATED(mixed_cdft%matrix%mixed_matrix_s))
1232 mixed_mo_coeff => mixed_cdft%matrix%mixed_mo_coeff
1233 w_matrix => mixed_cdft%matrix%w_matrix
1234 mixed_matrix_s => mixed_cdft%matrix%mixed_matrix_s
1235 IF (mixed_cdft%calculate_metric)
THEN
1236 cpassert(
ASSOCIATED(mixed_cdft%matrix%density_matrix))
1237 density_matrix => mixed_cdft%matrix%density_matrix
1240 nvar =
SIZE(w_matrix, 2)
1241 nspins =
SIZE(mixed_mo_coeff, 2)
1243 ALLOCATE (nrow_mo(nspins), ncol_mo(nspins))
1244 DO ispin = 1, nspins
1245 CALL cp_fm_get_info(mixed_mo_coeff(1, ispin), ncol_global=check_mo(1), nrow_global=check_ao(1))
1246 DO iforce_eval = 2, nforce_eval
1247 CALL cp_fm_get_info(mixed_mo_coeff(iforce_eval, ispin), ncol_global=check_mo(2), nrow_global=check_ao(2))
1248 IF (check_ao(1) /= check_ao(2))
THEN
1249 CALL cp_abort(__location__, &
1250 "The number of atomic orbitals must be the same in every CDFT state.")
1252 IF (check_mo(1) /= check_mo(2))
THEN
1253 CALL cp_abort(__location__, &
1254 "The number of molecular orbitals must be the same in every CDFT state.")
1259 npermutations = nforce_eval*(nforce_eval - 1)/2
1260 ALLOCATE (w_matrix_mo(nforce_eval, nforce_eval, nvar))
1261 ALLOCATE (mo_overlap(npermutations), s_det(npermutations, nspins))
1262 ALLOCATE (a(nspins, nvar, npermutations), b(nspins, nvar, npermutations))
1265 IF (mixed_cdft%calculate_metric)
THEN
1266 ALLOCATE (density_matrix_diff(npermutations, nspins))
1267 DO ispin = 1, nspins
1268 DO ipermutation = 1, npermutations
1269 NULLIFY (density_matrix_diff(ipermutation, ispin)%matrix)
1270 CALL dbcsr_init_p(density_matrix_diff(ipermutation, ispin)%matrix)
1272 CALL dbcsr_copy(density_matrix_diff(ipermutation, ispin)%matrix, &
1273 density_matrix(istate, ispin)%matrix, name=
"DENSITY_MATRIX")
1278 uniform_occupation = .NOT.
ALLOCATED(mixed_cdft%occupations)
1279 should_scale = .false.
1280 IF (.NOT. uniform_occupation)
THEN
1281 ALLOCATE (homo(nforce_eval, nspins))
1284 IF (eps_occupied > 1.0_dp .OR. eps_occupied < 0.0_dp)
THEN
1285 CALL cp_abort(__location__, &
1286 "Keyword EPS_OCCUPIED only accepts values between 0.0 and 1.0")
1288 IF (mixed_cdft%eps_svd == 0.0_dp)
THEN
1289 CALL cp_warn(__location__, &
1290 "The usage of SVD based matrix inversions with fractionally occupied "// &
1291 "orbitals is strongly recommended to screen nearly orthogonal states.")
1293 CALL section_vals_val_get(mixed_cdft_section,
"SCALE_WITH_OCCUPATION_NUMBERS", l_val=should_scale)
1296 DO ispin = 1, nspins
1299 NULLIFY (fm_struct_mo, mo_mo_fmstruct)
1300 CALL cp_fm_get_info(mixed_mo_coeff(1, ispin), ncol_global=ncol_mo(ispin), nrow_global=nrow_mo(ispin))
1301 nao = nrow_mo(ispin)
1302 IF (uniform_occupation)
THEN
1303 nmo = ncol_mo(ispin)
1305 nmo = ncol_mo(ispin)
1307 homo(:, ispin) = nmo
1308 DO istate = 1, nforce_eval
1310 IF (mixed_cdft%occupations(istate, ispin)%array(j) >= eps_occupied)
THEN
1311 homo(istate, ispin) = j
1319 nmo = maxval(homo(:, ispin))
1321 nelectron_mismatch = .false.
1322 nelectron_tot = sum(mixed_cdft%occupations(1, ispin)%array(1:nmo))
1323 DO istate = 2, nforce_eval
1324 IF (abs(sum(mixed_cdft%occupations(istate, ispin)%array(1:nmo)) - nelectron_tot) > 1.0e-4_dp)
THEN
1325 nelectron_mismatch = .true.
1328 IF (any(homo(:, ispin) /= nmo))
THEN
1329 IF (ispin == 1)
THEN
1330 CALL cp_warn(__location__, &
1331 "The number of occupied alpha MOs is not constant across all CDFT states. "// &
1332 "Calculation proceeds but the results will likely be meaningless.")
1334 CALL cp_warn(__location__, &
1335 "The number of occupied beta MOs is not constant across all CDFT states. "// &
1336 "Calculation proceeds but the results will likely be meaningless.")
1338 ELSE IF (nelectron_mismatch)
THEN
1339 IF (ispin == 1)
THEN
1340 CALL cp_warn(__location__, &
1341 "The number of alpha electrons is not constant across all CDFT states. "// &
1342 "Calculation proceeds but the results will likely be meaningless.")
1344 CALL cp_warn(__location__, &
1345 "The number of beta electrons is not constant across all CDFT states. "// &
1346 "Calculation proceeds but the results will likely be meaningless.")
1351 context=mixed_cdft%blacs_env, para_env=force_env%para_env)
1353 context=mixed_cdft%blacs_env, para_env=force_env%para_env)
1355 CALL cp_fm_create(matrix=tmp2, matrix_struct=fm_struct_mo, &
1356 name=
"ET_TMP_"//trim(adjustl(
cp_to_string(ispin)))//
"_MATRIX")
1358 CALL cp_fm_create(matrix=inverse_mat, matrix_struct=mo_mo_fmstruct, &
1359 name=
"INVERSE_"//trim(adjustl(
cp_to_string(ispin)))//
"_MATRIX")
1360 CALL cp_fm_create(matrix=tinverse, matrix_struct=mo_mo_fmstruct, &
1361 name=
"T_INVERSE_"//trim(adjustl(
cp_to_string(ispin)))//
"_MATRIX")
1362 DO istate = 1, npermutations
1363 CALL cp_fm_create(matrix=mo_overlap(istate), matrix_struct=mo_mo_fmstruct, &
1364 name=
"MO_OVERLAP_"//trim(adjustl(
cp_to_string(istate)))//
"_"// &
1368 DO istate = 1, nforce_eval
1369 DO jstate = 1, nforce_eval
1370 IF (istate == jstate) cycle
1371 CALL cp_fm_create(matrix=w_matrix_mo(istate, jstate, ivar), matrix_struct=mo_mo_fmstruct, &
1372 name=
"W_"//trim(adjustl(
cp_to_string(istate)))//
"_"// &
1380 IF (.NOT. uniform_occupation)
THEN
1381 DO iforce_eval = 1, nforce_eval
1382 CALL cp_fm_to_fm(mixed_mo_coeff(iforce_eval, ispin), tmp2, nmo, 1, 1)
1384 CALL cp_fm_create(mixed_mo_coeff(iforce_eval, ispin), &
1385 matrix_struct=tmp2%matrix_struct, &
1386 name=
"MO_COEFF_"//trim(adjustl(
cp_to_string(iforce_eval)))//
"_" &
1388 CALL cp_fm_to_fm(tmp2, mixed_mo_coeff(iforce_eval, ispin))
1389 IF (should_scale)
THEN
1391 mixed_cdft%occupations(iforce_eval, ispin)%array(1:nmo))
1393 DEALLOCATE (mixed_cdft%occupations(iforce_eval, ispin)%array)
1398 DO istate = 1, nforce_eval
1399 DO jstate = istate + 1, nforce_eval
1400 ipermutation = ipermutation + 1
1402 tmp2, nmo, 1.0_dp, 0.0_dp)
1404 mixed_mo_coeff(jstate, ispin), &
1405 tmp2, 0.0_dp, mo_overlap(ipermutation))
1408 "# MO overlap matrix (step "//trim(adjustl(
cp_to_string(mixed_cdft%sim_step)))// &
1409 "): CDFT states "//trim(adjustl(
cp_to_string(istate)))//
" and "// &
1417 DO jstate = 1, nforce_eval
1418 DO istate = 1, nforce_eval
1419 IF (istate == jstate) cycle
1422 mixed_mo_coeff(istate, ispin), &
1423 tmp2, nmo, 1.0_dp, 0.0_dp)
1425 mixed_mo_coeff(jstate, ispin), &
1426 tmp2, 0.0_dp, w_matrix_mo(istate, jstate, ivar))
1430 DO ipermutation = 1, npermutations
1433 IF (print_mo_eigval)
THEN
1435 CALL cp_fm_invert(mo_overlap(ipermutation), inverse_mat, &
1436 s_det(ipermutation, ispin), eps_svd=mixed_cdft%eps_svd, &
1438 IF (moeigvalunit > 0)
THEN
1439 IF (mixed_cdft%eps_svd == 0.0_dp)
THEN
1440 WRITE (moeigvalunit,
'(A,I2,A,I2,A,I1,A)') &
1441 "# MO Overlap matrix eigenvalues for CDFT states ", istate,
" and ", jstate, &
1442 " (spin ", ispin,
")"
1444 WRITE (moeigvalunit,
'(A,I2,A,I2,A,I1,A)') &
1445 "# MO Overlap matrix singular values for CDFT states ", istate,
" and ", jstate, &
1446 " (spin ", ispin,
")"
1448 WRITE (moeigvalunit,
'(A1, A9, A12)')
"#",
"Index", adjustl(
"Value")
1449 DO j = 1,
SIZE(mo_eigval)
1450 WRITE (moeigvalunit,
'(I10, F12.8)') j, mo_eigval(j)
1453 DEALLOCATE (mo_eigval)
1455 CALL cp_fm_invert(mo_overlap(ipermutation), inverse_mat, &
1456 s_det(ipermutation, ispin), eps_svd=mixed_cdft%eps_svd)
1458 CALL cp_fm_get_info(inverse_mat, nrow_local=nrow_local, ncol_local=ncol_local)
1460 DO j = 1, ncol_local
1461 DO k = 1, nrow_local
1463 b(ispin, ivar, ipermutation) = b(ispin, ivar, ipermutation) + &
1464 w_matrix_mo(jstate, istate, ivar)%local_data(k, j)* &
1465 inverse_mat%local_data(k, j)
1471 DO j = 1, ncol_local
1472 DO k = 1, nrow_local
1474 a(ispin, ivar, ipermutation) = a(ispin, ivar, ipermutation) + &
1475 w_matrix_mo(istate, jstate, ivar)%local_data(k, j)* &
1476 tinverse%local_data(k, j)
1482 SELECT CASE (mixed_cdft%constraint_type(ivar, istate))
1486 IF (ispin == 2) a(ispin, ivar, ipermutation) = -a(ispin, ivar, ipermutation)
1489 IF (ispin == 2) a(ispin, ivar, ipermutation) = 0.0_dp
1492 IF (ispin == 1) a(ispin, ivar, ipermutation) = 0.0_dp
1494 cpabort(
"Unknown constraint type.")
1496 SELECT CASE (mixed_cdft%constraint_type(ivar, jstate))
1500 IF (ispin == 2) b(ispin, ivar, ipermutation) = -b(ispin, ivar, ipermutation)
1503 IF (ispin == 2) b(ispin, ivar, ipermutation) = 0.0_dp
1506 IF (ispin == 1) b(ispin, ivar, ipermutation) = 0.0_dp
1508 cpabort(
"Unknown constraint type.")
1512 IF (mixed_cdft%calculate_metric)
THEN
1513 CALL dbcsr_add(density_matrix_diff(ipermutation, ispin)%matrix, &
1514 density_matrix(jstate, ispin)%matrix, -1.0_dp, 1.0_dp)
1517 CALL force_env%para_env%sum(a(ispin, :, ipermutation))
1518 CALL force_env%para_env%sum(b(ispin, :, ipermutation))
1523 DO jstate = 1, nforce_eval
1524 DO istate = 1, nforce_eval
1525 IF (istate == jstate) cycle
1530 DO ipermutation = 1, npermutations
1536 DEALLOCATE (mo_overlap)
1537 DEALLOCATE (w_matrix_mo)
1538 IF (.NOT. uniform_occupation)
THEN
1540 DEALLOCATE (mixed_cdft%occupations)
1544 "MIXED%MIXED_CDFT%PRINT%PROGRAM_RUN_INFO", on_file=.true.)
1546 IF (print_mo_eigval)
THEN
1548 "MIXED%MIXED_CDFT%PRINT%PROGRAM_RUN_INFO", on_file=.true.)
1551 ALLOCATE (wda(nvar, npermutations))
1552 ALLOCATE (sda(npermutations))
1553 IF (.NOT. mixed_cdft%identical_constraints)
ALLOCATE (wad(nvar, npermutations))
1554 DO ipermutation = 1, npermutations
1555 IF (nspins == 2)
THEN
1556 sda(ipermutation) = abs(s_det(ipermutation, 1)*s_det(ipermutation, 2))
1558 sda(ipermutation) = s_det(ipermutation, 1)**2
1562 IF (mixed_cdft%identical_constraints)
THEN
1563 wda(ivar, ipermutation) = (sum(a(:, ivar, ipermutation)) + sum(b(:, ivar, ipermutation)))* &
1564 sda(ipermutation)/2.0_dp
1566 wda(ivar, ipermutation) = sum(a(:, ivar, ipermutation))*sda(ipermutation)
1567 wad(ivar, ipermutation) = sum(b(:, ivar, ipermutation))*sda(ipermutation)
1571 DEALLOCATE (a, b, s_det)
1573 ALLOCATE (w_diagonal(nvar, nforce_eval), strength(nvar, nforce_eval), energy(nforce_eval))
1575 DO iforce_eval = 1, nforce_eval
1576 strength(:, iforce_eval) = mixed_env%strength(iforce_eval, :)
1579 DO iforce_eval = 1, nforce_eval
1580 IF (.NOT.
ASSOCIATED(force_env%sub_force_env(iforce_eval)%force_env)) cycle
1581 IF (force_env%mixed_env%do_mixed_qmmm_cdft)
THEN
1582 qs_env => force_env%sub_force_env(iforce_eval)%force_env%qmmm_env%qs_env
1584 CALL force_env_get(force_env%sub_force_env(iforce_eval)%force_env, qs_env=qs_env)
1586 CALL get_qs_env(qs_env, energy=energy_qs, dft_control=dft_control)
1587 IF (force_env%sub_force_env(iforce_eval)%force_env%para_env%is_source())
THEN
1588 w_diagonal(:, iforce_eval) = dft_control%qs_control%cdft_control%value(:)
1592 energy(iforce_eval) = energy_qs%total - energy_qs%cdft
1595 CALL force_env%para_env%sum(w_diagonal)
1596 CALL force_env%para_env%sum(energy)
1598 energy=energy, strength=strength)
1601 ALLOCATE (s_mat(nforce_eval, nforce_eval))
1602 DO istate = 1, nforce_eval
1603 s_mat(istate, istate) = 1.0_dp
1605 DO ipermutation = 1, npermutations
1607 s_mat(istate, jstate) = sda(ipermutation)
1608 s_mat(jstate, istate) = sda(ipermutation)
1612 ALLOCATE (eigenv(nforce_eval), tmp_mat(nforce_eval, nforce_eval))
1615 DO istate = 1, nforce_eval
1616 IF (eigenv(istate) < 1.0e-14_dp)
THEN
1618 eigenv(istate) = 1.0e-14_dp
1619 CALL cp_warn(__location__, &
1620 "The overlap matrix is numerically nearly singular. "// &
1621 "Calculation proceeds but the results might be meaningless.")
1623 tmp_mat(istate, istate) = 1.0_dp/sqrt(eigenv(istate))
1625 tmp_mat(:, :) = matmul(tmp_mat, transpose(s_mat))
1626 s_mat(:, :) = matmul(s_mat, tmp_mat)
1628 DEALLOCATE (eigenv, tmp_mat, s_mat)
1630 ALLOCATE (h_mat(nforce_eval, nforce_eval))
1631 IF (mixed_cdft%nonortho_coupling)
ALLOCATE (coupling_nonortho(npermutations))
1632 DO istate = 1, nforce_eval
1633 h_mat(istate, istate) = energy(istate)
1635 DO ipermutation = 1, npermutations
1641 sum_b(1) = sum_b(1) + strength(ivar, jstate)*w_diagonal(ivar, jstate)
1643 sum_a(1) = sum_a(1) + strength(ivar, istate)*w_diagonal(ivar, istate)
1644 IF (mixed_cdft%identical_constraints)
THEN
1646 sum_b(2) = sum_b(2) + strength(ivar, jstate)*wda(ivar, ipermutation)
1648 sum_a(2) = sum_a(2) + strength(ivar, istate)*wda(ivar, ipermutation)
1651 sum_b(2) = sum_b(2) + strength(ivar, jstate)*wad(ivar, ipermutation)
1653 sum_a(2) = sum_a(2) + strength(ivar, istate)*wda(ivar, ipermutation)
1658 c(1) = (energy(jstate) + sum_b(1))*sda(ipermutation) - sum_b(2)
1660 c(2) = (energy(istate) + sum_a(1))*sda(ipermutation) - sum_a(2)
1662 h_mat(istate, jstate) = (c(1) + c(2))*0.5_dp
1663 h_mat(jstate, istate) = h_mat(istate, jstate)
1664 IF (mixed_cdft%nonortho_coupling) coupling_nonortho(ipermutation) = h_mat(istate, jstate)
1667 DEALLOCATE (h_mat, w_diagonal, wda, strength, energy, sda)
1668 IF (
ALLOCATED(wad))
DEALLOCATE (wad)
1669 IF (mixed_cdft%nonortho_coupling)
THEN
1671 DEALLOCATE (coupling_nonortho)
1674 IF (mixed_cdft%calculate_metric)
CALL mixed_cdft_calculate_metric(force_env, mixed_cdft, density_matrix_diff, ncol_mo)
1677 IF (mixed_cdft%wfn_overlap_method)
THEN
1678 IF (.NOT. uniform_occupation)
THEN
1679 CALL cp_abort(__location__, &
1680 "Wavefunction overlap method supports only uniformly occupied MOs.")
1682 CALL mixed_cdft_wfn_overlap_method(force_env, mixed_cdft, ncol_mo, nrow_mo)
1685 DEALLOCATE (nrow_mo, ncol_mo)
1687 CALL timestop(handle)
1689 END SUBROUTINE mixed_cdft_interaction_matrices
1697 SUBROUTINE mixed_cdft_calculate_coupling_low(force_env)
1700 CHARACTER(len=*),
PARAMETER :: routinen =
'mixed_cdft_calculate_coupling_low'
1702 INTEGER :: handle, ipermutation, istate, jstate, &
1703 nforce_eval, npermutations, nvar
1704 LOGICAL :: use_lowdin, use_rotation
1705 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: coupling_lowdin, coupling_rotation, &
1707 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: tmp_mat, w_mat
1710 NULLIFY (mixed_cdft)
1711 cpassert(
ASSOCIATED(force_env))
1712 CALL get_mixed_env(force_env%mixed_env, cdft_control=mixed_cdft)
1713 CALL timeset(routinen, handle)
1714 cpassert(
ASSOCIATED(mixed_cdft))
1715 cpassert(
ALLOCATED(mixed_cdft%results%W_diagonal))
1716 cpassert(
ALLOCATED(mixed_cdft%results%Wda))
1717 cpassert(
ALLOCATED(mixed_cdft%results%S_minushalf))
1718 cpassert(
ALLOCATED(mixed_cdft%results%H))
1723 nforce_eval =
SIZE(mixed_cdft%results%H, 1)
1724 nvar =
SIZE(mixed_cdft%results%Wda, 1)
1725 npermutations = nforce_eval*(nforce_eval - 1)/2
1726 ALLOCATE (tmp_mat(nforce_eval, nforce_eval))
1727 IF (nvar == 1 .AND. mixed_cdft%identical_constraints)
THEN
1728 use_rotation = .true.
1729 use_lowdin = mixed_cdft%use_lowdin
1731 use_rotation = .false.
1735 IF (use_rotation)
THEN
1737 ALLOCATE (w_mat(nforce_eval, nforce_eval), coupling_rotation(npermutations))
1738 ALLOCATE (eigenv(nforce_eval))
1740 DO istate = 1, nforce_eval
1741 w_mat(istate, istate) = sum(mixed_cdft%results%W_diagonal(:, istate))
1744 DO ipermutation = 1, npermutations
1746 w_mat(istate, jstate) = sum(mixed_cdft%results%Wda(:, ipermutation))
1747 w_mat(jstate, istate) = w_mat(istate, jstate)
1751 tmp_mat(:, :) = matmul(w_mat, mixed_cdft%results%S_minushalf)
1752 w_mat(:, :) = matmul(mixed_cdft%results%S_minushalf, tmp_mat)
1754 tmp_mat(:, :) = matmul(mixed_cdft%results%S_minushalf, w_mat)
1756 w_mat(:, :) = matmul(mixed_cdft%results%H, tmp_mat)
1757 w_mat(:, :) = matmul(transpose(tmp_mat), w_mat)
1758 DO ipermutation = 1, npermutations
1760 coupling_rotation(ipermutation) = w_mat(istate, jstate)
1763 DEALLOCATE (w_mat, coupling_rotation, eigenv)
1766 IF (use_lowdin)
THEN
1767 ALLOCATE (coupling_lowdin(npermutations))
1768 tmp_mat(:, :) = matmul(mixed_cdft%results%H, mixed_cdft%results%S_minushalf)
1770 tmp_mat(:, :) = matmul(mixed_cdft%results%S_minushalf, tmp_mat)
1771 DO ipermutation = 1, npermutations
1773 coupling_lowdin(ipermutation) = tmp_mat(istate, jstate)
1776 DEALLOCATE (coupling_lowdin)
1778 DEALLOCATE (tmp_mat)
1779 CALL timestop(handle)
1781 END SUBROUTINE mixed_cdft_calculate_coupling_low
1789 SUBROUTINE mixed_cdft_configuration_interaction(force_env)
1792 CHARACTER(len=*),
PARAMETER :: routinen =
'mixed_cdft_configuration_interaction'
1794 INTEGER :: handle, info, iounit, istate, ivar, &
1795 nforce_eval, work_array_size
1796 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: eigenv, work
1797 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: h_mat, h_mat_copy, s_mat, s_mat_copy
1798 REAL(kind=
dp),
EXTERNAL :: dnrm2
1805 NULLIFY (logger, force_env_section, print_section, mixed_cdft)
1807 cpassert(
ASSOCIATED(force_env))
1808 CALL get_mixed_env(force_env%mixed_env, cdft_control=mixed_cdft)
1809 cpassert(
ASSOCIATED(mixed_cdft))
1811 IF (.NOT. mixed_cdft%do_ci)
RETURN
1814 CALL timeset(routinen, handle)
1816 force_env_section=force_env_section)
1820 cpassert(
ALLOCATED(mixed_cdft%results%S))
1821 cpassert(
ALLOCATED(mixed_cdft%results%H))
1822 nforce_eval =
SIZE(mixed_cdft%results%S, 1)
1823 ALLOCATE (s_mat(nforce_eval, nforce_eval), h_mat(nforce_eval, nforce_eval))
1824 ALLOCATE (eigenv(nforce_eval))
1825 s_mat(:, :) = mixed_cdft%results%S(:, :)
1826 h_mat(:, :) = mixed_cdft%results%H(:, :)
1830 ALLOCATE (h_mat_copy(nforce_eval, nforce_eval), s_mat_copy(nforce_eval, nforce_eval))
1831 h_mat_copy(:, :) = h_mat(:, :)
1832 s_mat_copy(:, :) = s_mat(:, :)
1833 CALL dsygv(1,
'V',
'U', nforce_eval, h_mat_copy, nforce_eval, s_mat_copy, nforce_eval, eigenv, work, -1, info)
1834 work_array_size = nint(work(1))
1835 DEALLOCATE (h_mat_copy, s_mat_copy)
1838 ALLOCATE (work(work_array_size))
1842 CALL dsygv(1,
'V',
'U', nforce_eval, h_mat, nforce_eval, s_mat, nforce_eval, eigenv, work, work_array_size, info)
1844 IF (info > nforce_eval)
THEN
1845 cpabort(
"Matrix S is not positive definite")
1847 cpabort(
"Diagonalization of H matrix failed.")
1852 DO ivar = 1, nforce_eval
1853 h_mat(:, ivar) = h_mat(:, ivar)/dnrm2(nforce_eval, h_mat(:, ivar), 1)
1856 IF (iounit > 0)
THEN
1857 WRITE (iounit,
'(/,T3,A)')
'------------------ CDFT Configuration Interaction (CDFT-CI) ------------------'
1858 DO ivar = 1, nforce_eval
1860 WRITE (iounit,
'(T3,A,T58,(3X,F20.14))')
'Ground state energy:', eigenv(ivar)
1862 WRITE (iounit,
'(/,T3,A,I2,A,T58,(3X,F20.14))')
'Excited state (', ivar - 1,
' ) energy:', eigenv(ivar)
1864 DO istate = 1, nforce_eval, 2
1865 IF (istate == 1)
THEN
1866 WRITE (iounit,
'(T3,A,T54,(3X,2F12.6))') &
1867 'Expansion coefficients:', h_mat(istate, ivar), h_mat(istate + 1, ivar)
1868 ELSE IF (istate < nforce_eval)
THEN
1869 WRITE (iounit,
'(T54,(3X,2F12.6))') h_mat(istate, ivar), h_mat(istate + 1, ivar)
1871 WRITE (iounit,
'(T54,(3X,F12.6))') h_mat(istate, ivar)
1875 WRITE (iounit,
'(T3,A)') &
1876 '------------------------------------------------------------------------------'
1878 DEALLOCATE (s_mat, h_mat, eigenv)
1880 "MIXED%MIXED_CDFT%PRINT%PROGRAM_RUN_INFO")
1881 CALL timestop(handle)
1883 END SUBROUTINE mixed_cdft_configuration_interaction
1892 SUBROUTINE mixed_cdft_block_diag(force_env)
1895 CHARACTER(len=*),
PARAMETER :: routinen =
'mixed_cdft_block_diag'
1897 INTEGER :: handle, i, iounit, irecursion, j, n, &
1898 nblk, nforce_eval, nrecursion
1899 LOGICAL :: ignore_excited
1902 TYPE(
cp_2d_r_p_type),
ALLOCATABLE,
DIMENSION(:) :: h_block, s_block
1909 NULLIFY (logger, force_env_section, print_section, mixed_cdft)
1911 cpassert(
ASSOCIATED(force_env))
1912 CALL get_mixed_env(force_env%mixed_env, cdft_control=mixed_cdft)
1913 cpassert(
ASSOCIATED(mixed_cdft))
1915 IF (.NOT. mixed_cdft%block_diagonalize)
RETURN
1918 CALL timeset(routinen, handle)
1920 cpassert(
ALLOCATED(mixed_cdft%results%S))
1921 cpassert(
ALLOCATED(mixed_cdft%results%H))
1922 nforce_eval =
SIZE(mixed_cdft%results%S, 1)
1925 force_env_section=force_env_section)
1932 DO irecursion = 1, nrecursion
1934 IF (iounit > 0 .AND. irecursion == 1)
THEN
1935 WRITE (iounit,
'(/,T3,A)')
'-------------------------- CDFT BLOCK DIAGONALIZATION ------------------------'
1936 WRITE (iounit,
'(T3,A)')
'Block diagonalizing the mixed CDFT Hamiltonian'
1937 WRITE (iounit,
'(T3,A,I3)')
'Number of blocks:', nblk
1938 WRITE (iounit,
'(T3,A,L3)')
'Ignoring excited states within blocks:', ignore_excited
1939 WRITE (iounit,
'(/,T3,A)')
'List of CDFT states for each block'
1941 WRITE (iounit,
'(T6,A,I3,A,6I3)')
'Block', i,
':', (blocks(i)%array(j), j=1,
SIZE(blocks(i)%array))
1945 IF (irecursion > 1)
THEN
1947 ALLOCATE (blocks(nblk))
1950 NULLIFY (blocks(i)%array)
1951 ALLOCATE (blocks(i)%array(2))
1952 blocks(i)%array = [j, j + 1]
1956 IF (iounit > 0)
THEN
1957 WRITE (iounit,
'(/, T3,A)')
'Recursive block diagonalization of the mixed CDFT Hamiltonian'
1958 WRITE (iounit,
'(T6,A)')
'Block diagonalization is continued until only two matrix blocks remain.'
1959 WRITE (iounit,
'(T6,A)')
'The new blocks are formed by collecting pairs of blocks from the previous'
1960 WRITE (iounit,
'(T6,A)')
'block diagonalized matrix in ascending order.'
1961 WRITE (iounit,
'(/,T3,A,I3,A,I3)')
'Recursion step:', irecursion - 1,
' of ', nrecursion - 1
1962 WRITE (iounit,
'(/,T3,A)')
'List of old block indices for each new block'
1964 WRITE (iounit,
'(T6,A,I3,A,6I3)')
'Block', i,
':', (blocks(i)%array(j), j=1,
SIZE(blocks(i)%array))
1973 IF (ignore_excited)
THEN
1981 DEALLOCATE (h_block(i)%array)
1982 DEALLOCATE (s_block(i)%array)
1983 DEALLOCATE (eigenvalues(i)%array)
1984 DEALLOCATE (blocks(i)%array)
1986 DEALLOCATE (h_block, s_block, eigenvalues, blocks)
1988 IF (iounit > 0)
THEN
1989 WRITE (iounit,
'(T3,A)') &
1990 '------------------------------------------------------------------------------'
1993 "MIXED%MIXED_CDFT%PRINT%PROGRAM_RUN_INFO")
1994 CALL timestop(handle)
1996 END SUBROUTINE mixed_cdft_block_diag
2007 SUBROUTINE mixed_cdft_calculate_metric(force_env, mixed_cdft, density_matrix_diff, ncol_mo)
2010 TYPE(
dbcsr_p_type),
DIMENSION(:, :),
POINTER :: density_matrix_diff
2011 INTEGER,
DIMENSION(:) :: ncol_mo
2013 CHARACTER(len=*),
PARAMETER :: routinen =
'mixed_cdft_calculate_metric'
2015 INTEGER :: handle, ipermutation, ispin, j, &
2016 nforce_eval, npermutations, nspins
2017 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: evals
2018 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: metric
2021 CALL timeset(routinen, handle)
2022 nforce_eval =
SIZE(mixed_cdft%results%H, 1)
2023 npermutations = nforce_eval*(nforce_eval - 1)/2
2024 nspins =
SIZE(density_matrix_diff, 2)
2025 ALLOCATE (metric(npermutations, nspins))
2027 CALL dbcsr_create(e_vectors, template=density_matrix_diff(1, 1)%matrix)
2028 DO ispin = 1, nspins
2029 ALLOCATE (evals(ncol_mo(ispin)))
2030 DO ipermutation = 1, npermutations
2032 IF (nspins == 1)
THEN
2033 CALL dbcsr_scale(density_matrix_diff(ipermutation, 1)%matrix, alpha_scalar=0.5_dp)
2036 CALL cp_dbcsr_syevd(density_matrix_diff(ipermutation, ispin)%matrix, e_vectors, evals, &
2037 para_env=force_env%para_env, blacs_env=mixed_cdft%blacs_env)
2039 DO j = 1, ncol_mo(ispin)
2040 metric(ipermutation, ispin) = metric(ipermutation, ispin) + (evals(j)**2 - evals(j)**4)
2046 DEALLOCATE (density_matrix_diff)
2047 metric(:, :) = metric(:, :)/4.0_dp
2050 CALL timestop(handle)
2052 END SUBROUTINE mixed_cdft_calculate_metric
2063 SUBROUTINE mixed_cdft_wfn_overlap_method(force_env, mixed_cdft, ncol_mo, nrow_mo)
2066 INTEGER,
DIMENSION(:) :: ncol_mo, nrow_mo
2068 CHARACTER(len=*),
PARAMETER :: routinen =
'mixed_cdft_wfn_overlap_method'
2070 CHARACTER(LEN=default_path_length) :: file_name
2071 INTEGER :: handle, ipermutation, ispin, istate, &
2072 jstate, nao, nforce_eval, nmo, &
2073 npermutations, nspins
2074 LOGICAL :: exist, natom_mismatch
2075 REAL(kind=
dp) :: energy_diff, maxocc, sda
2076 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: coupling_wfn
2077 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :, :) :: overlaps
2080 TYPE(
cp_fm_type) :: inverse_mat, mo_overlap_wfn, mo_tmp
2081 TYPE(
cp_fm_type),
DIMENSION(:, :),
POINTER :: mixed_mo_coeff
2085 TYPE(
mo_set_type),
ALLOCATABLE,
DIMENSION(:) :: mo_set
2087 TYPE(
qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
2090 NULLIFY (mixed_cdft_section, subsys_mix, particle_set, qs_kind_set, atomic_kind_set, &
2091 mixed_mo_coeff, mixed_matrix_s, force_env_section)
2094 CALL timeset(routinen, handle)
2095 nforce_eval =
SIZE(mixed_cdft%results%H, 1)
2096 npermutations = nforce_eval*(nforce_eval - 1)/2
2097 nspins =
SIZE(nrow_mo)
2098 mixed_mo_coeff => mixed_cdft%matrix%mixed_mo_coeff
2099 mixed_matrix_s => mixed_cdft%matrix%mixed_matrix_s
2101 force_env_section=force_env_section)
2103 ALLOCATE (mo_set(nspins))
2104 IF (nspins == 2)
THEN
2109 DO ispin = 1, nspins
2110 nao = nrow_mo(ispin)
2111 nmo = ncol_mo(ispin)
2113 CALL allocate_mo_set(mo_set(ispin), nao=nao, nmo=nmo, nelectron=int(maxocc*nmo), &
2114 n_el_f=real(maxocc*nmo,
dp), maxocc=maxocc, &
2115 flexible_electron_count=0.0_dp)
2116 CALL set_mo_set(mo_set(ispin), uniform_occupation=.true., homo=nmo)
2117 ALLOCATE (mo_set(ispin)%mo_coeff)
2119 matrix_struct=mixed_mo_coeff(1, ispin)%matrix_struct, &
2120 name=
"GS_MO_COEFF"//trim(adjustl(
cp_to_string(ispin)))//
"MATRIX")
2121 ALLOCATE (mo_set(ispin)%eigenvalues(nmo))
2122 ALLOCATE (mo_set(ispin)%occupation_numbers(nmo))
2125 IF (force_env%mixed_env%do_mixed_qmmm_cdft)
THEN
2127 CALL cp_abort(__location__, &
2128 "QMMM + wavefunction overlap method not supported.")
2132 CALL cp_subsys_get(subsys_mix, atomic_kind_set=atomic_kind_set, particle_set=particle_set)
2133 cpassert(
ASSOCIATED(mixed_cdft%qs_kind_set))
2134 IF (force_env%para_env%is_source())
THEN
2137 CALL force_env%para_env%bcast(exist)
2138 CALL force_env%para_env%bcast(file_name)
2139 IF (.NOT. exist)
THEN
2140 CALL cp_abort(__location__, &
2141 "User requested to restart the wavefunction from the file named: "// &
2142 trim(file_name)//
". This file does not exist. Please check the existence of"// &
2143 " the file or change properly the value of the keyword WFN_RESTART_FILE_NAME in"// &
2144 " section FORCE_EVAL\MIXED\MIXED_CDFT.")
2147 para_env=force_env%para_env, id_nr=0, multiplicity=mixed_cdft%multiplicity, &
2148 dft_section=mixed_cdft_section, natom_mismatch=natom_mismatch, &
2150 IF (natom_mismatch)
THEN
2151 CALL cp_abort(__location__, &
2152 "Restart wfn file has a wrong number of atoms")
2155 DO ispin = 1, nspins
2156 IF (mixed_cdft%has_unit_metric)
THEN
2159 CALL make_basis_sm(mo_set(ispin)%mo_coeff, ncol_mo(ispin), mixed_matrix_s)
2163 ALLOCATE (coupling_wfn(npermutations))
2164 ALLOCATE (overlaps(2, npermutations, nspins))
2166 DO ispin = 1, nspins
2168 nao = nrow_mo(ispin)
2169 nmo = ncol_mo(ispin)
2171 context=mixed_cdft%blacs_env, para_env=force_env%para_env)
2172 CALL cp_fm_create(matrix=mo_overlap_wfn, matrix_struct=mo_mo_fmstruct, &
2173 name=
"MO_OVERLAP_MATRIX_WFN")
2174 CALL cp_fm_create(matrix=inverse_mat, matrix_struct=mo_mo_fmstruct, &
2175 name=
"INVERSE_MO_OVERLAP_MATRIX_WFN")
2178 matrix_struct=mixed_mo_coeff(1, ispin)%matrix_struct, &
2179 name=
"OVERLAP_MO_COEFF_WFN")
2180 DO ipermutation = 1, npermutations
2184 mo_tmp, nmo, 1.0_dp, 0.0_dp)
2188 mixed_mo_coeff(istate, ispin), &
2189 mo_tmp, 0.0_dp, mo_overlap_wfn)
2190 CALL cp_fm_invert(mo_overlap_wfn, inverse_mat, overlaps(1, ipermutation, ispin), eps_svd=mixed_cdft%eps_svd)
2194 mixed_mo_coeff(jstate, ispin), &
2195 mo_tmp, 0.0_dp, mo_overlap_wfn)
2196 CALL cp_fm_invert(mo_overlap_wfn, inverse_mat, overlaps(2, ipermutation, ispin), eps_svd=mixed_cdft%eps_svd)
2204 DO ipermutation = 1, npermutations
2206 IF (nspins == 2)
THEN
2207 overlaps(1, ipermutation, 1) = abs(overlaps(1, ipermutation, 1)*overlaps(1, ipermutation, 2))
2208 overlaps(2, ipermutation, 1) = abs(overlaps(2, ipermutation, 1)*overlaps(2, ipermutation, 2))
2210 overlaps(1, ipermutation, 1) = overlaps(1, ipermutation, 1)**2
2211 overlaps(2, ipermutation, 1) = overlaps(2, ipermutation, 1)**2
2215 IF (abs(overlaps(1, ipermutation, 1) - overlaps(2, ipermutation, 1)) <= 1.0e-14_dp)
THEN
2216 CALL cp_warn(__location__, &
2217 "Coupling between states is singular and set to zero. "// &
2218 "Potential causes: coupling is computed between identical CDFT states or the spin/charge "// &
2219 "density is fully delocalized in the unconstrained ground state.")
2220 coupling_wfn(ipermutation) = 0.0_dp
2222 energy_diff = mixed_cdft%results%energy(jstate) - mixed_cdft%results%energy(istate)
2223 sda = mixed_cdft%results%S(istate, jstate)
2224 coupling_wfn(ipermutation) = abs((overlaps(1, ipermutation, 1)*overlaps(2, ipermutation, 1)/ &
2225 (overlaps(1, ipermutation, 1)**2 - overlaps(2, ipermutation, 1)**2))* &
2226 (energy_diff)/(1.0_dp - sda**2)* &
2227 (1.0_dp - (overlaps(1, ipermutation, 1)**2 + overlaps(2, ipermutation, 1)**2)/ &
2228 (2.0_dp*overlaps(1, ipermutation, 1)*overlaps(2, ipermutation, 1))* &
2232 DEALLOCATE (overlaps)
2234 DEALLOCATE (coupling_wfn)
2235 CALL timestop(handle)
2237 END SUBROUTINE mixed_cdft_wfn_overlap_method
2251 SUBROUTINE mixed_becke_constraint(force_env, calculate_forces)
2253 LOGICAL,
INTENT(IN) :: calculate_forces
2255 CHARACTER(len=*),
PARAMETER :: routinen =
'mixed_becke_constraint'
2258 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: catom
2259 LOGICAL :: in_memory, store_vectors
2260 LOGICAL,
ALLOCATABLE,
DIMENSION(:) :: is_constraint
2261 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: coefficients
2262 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: position_vecs, r12
2263 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :, :) :: pair_dist_vecs
2268 NULLIFY (mixed_env, mixed_cdft)
2269 store_vectors = .true.
2271 CALL timeset(routinen, handle)
2272 mixed_env => force_env%mixed_env
2274 CALL mixed_becke_constraint_init(force_env, mixed_cdft, calculate_forces, &
2275 is_constraint, in_memory, store_vectors, &
2276 r12, position_vecs, pair_dist_vecs, &
2277 coefficients, catom)
2278 CALL mixed_becke_constraint_low(force_env, mixed_cdft, in_memory, &
2279 is_constraint, store_vectors, r12, &
2280 position_vecs, pair_dist_vecs, &
2281 coefficients, catom)
2282 CALL timestop(handle)
2284 END SUBROUTINE mixed_becke_constraint
2303 SUBROUTINE mixed_becke_constraint_init(force_env, mixed_cdft, calculate_forces, &
2304 is_constraint, in_memory, store_vectors, &
2305 R12, position_vecs, pair_dist_vecs, coefficients, &
2309 LOGICAL,
INTENT(IN) :: calculate_forces
2310 LOGICAL,
ALLOCATABLE,
DIMENSION(:),
INTENT(OUT) :: is_constraint
2311 LOGICAL,
INTENT(OUT) :: in_memory
2312 LOGICAL,
INTENT(IN) :: store_vectors
2313 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :), &
2314 INTENT(out) :: r12, position_vecs
2315 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :, :), &
2316 INTENT(out) :: pair_dist_vecs
2317 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:), &
2318 INTENT(OUT) :: coefficients
2319 INTEGER,
ALLOCATABLE,
DIMENSION(:),
INTENT(out) :: catom
2321 CHARACTER(len=*),
PARAMETER :: routinen =
'mixed_becke_constraint_init'
2323 CHARACTER(len=2) :: element_symbol
2324 INTEGER :: atom_a, bounds(2), handle, i, iatom, iex, iforce_eval, ikind, iounit, ithread, j, &
2325 jatom, katom, my_work, my_work_size, natom, nforce_eval, nkind, np(3), npme, nthread, &
2326 numexp, offset_dlb, unit_nr
2327 INTEGER,
DIMENSION(2, 3) :: bo, bo_conf
2328 INTEGER,
DIMENSION(:),
POINTER :: atom_list, cores, stride
2329 LOGICAL :: build, mpi_io
2330 REAL(kind=
dp) :: alpha, chi, coef, ircov, jrcov, ra(3), &
2332 REAL(kind=
dp),
DIMENSION(3) :: cell_v, dist_vec, dr, r, r1, shift
2333 REAL(kind=
dp),
DIMENSION(:),
POINTER :: radii_list
2334 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: pab
2345 TYPE(
qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
2349 NULLIFY (pab, cell, force_env_qs, particle_set, force_env_section, print_section, &
2350 qs_kind_set, particles, subsys_mix, rs_cavity, cavity_env, auxbas_pw_pool, &
2351 atomic_kind_set, radii_list, cdft_control)
2353 nforce_eval =
SIZE(force_env%sub_force_env)
2354 CALL timeset(routinen, handle)
2355 CALL force_env_get(force_env=force_env, force_env_section=force_env_section)
2356 IF (.NOT. force_env%mixed_env%do_mixed_qmmm_cdft)
THEN
2358 subsys=subsys_mix, &
2361 particles=particles, &
2362 particle_set=particle_set)
2364 DO iforce_eval = 1, nforce_eval
2365 IF (.NOT.
ASSOCIATED(force_env%sub_force_env(iforce_eval)%force_env)) cycle
2366 force_env_qs => force_env%sub_force_env(iforce_eval)%force_env
2368 CALL get_qs_env(force_env_qs%qmmm_env%qs_env, &
2369 cp_subsys=subsys_mix, &
2372 particles=particles, &
2373 particle_set=particle_set)
2375 natom =
SIZE(particles%els)
2377 cdft_control => mixed_cdft%cdft_control
2378 cpassert(
ASSOCIATED(cdft_control))
2379 IF (.NOT.
ASSOCIATED(cdft_control%becke_control%cutoffs))
THEN
2380 CALL cp_subsys_get(subsys_mix, atomic_kind_set=atomic_kind_set)
2381 ALLOCATE (cdft_control%becke_control%cutoffs(natom))
2382 SELECT CASE (cdft_control%becke_control%cutoff_type)
2384 cdft_control%becke_control%cutoffs(:) = cdft_control%becke_control%rglobal
2386 IF (.NOT.
SIZE(atomic_kind_set) ==
SIZE(cdft_control%becke_control%cutoffs_tmp))
THEN
2387 CALL cp_abort(__location__, &
2388 "Size of keyword BECKE_CONSTRAINT\ELEMENT_CUTOFFS does "// &
2389 "not match number of atomic kinds in the input coordinate file.")
2391 DO ikind = 1,
SIZE(atomic_kind_set)
2392 CALL get_atomic_kind(atomic_kind_set(ikind), natom=katom, atom_list=atom_list)
2394 atom_a = atom_list(iatom)
2395 cdft_control%becke_control%cutoffs(atom_a) = cdft_control%becke_control%cutoffs_tmp(ikind)
2398 DEALLOCATE (cdft_control%becke_control%cutoffs_tmp)
2402 IF (cdft_control%becke_control%adjust .AND. &
2403 .NOT.
ASSOCIATED(cdft_control%becke_control%aij))
THEN
2404 ALLOCATE (cdft_control%becke_control%aij(natom, natom))
2407 ALLOCATE (catom(cdft_control%natoms))
2408 IF (cdft_control%save_pot .OR. &
2409 cdft_control%becke_control%cavity_confine .OR. &
2410 cdft_control%becke_control%should_skip .OR. &
2411 mixed_cdft%first_iteration)
THEN
2412 ALLOCATE (is_constraint(natom))
2413 is_constraint = .false.
2415 in_memory = calculate_forces .AND. cdft_control%becke_control%in_memory
2416 IF (in_memory .NEQV. calculate_forces)
THEN
2417 CALL cp_abort(__location__, &
2418 "The flag BECKE_CONSTRAINT\IN_MEMORY must be activated "// &
2419 "for the calculation of mixed CDFT forces")
2421 IF (in_memory .OR. mixed_cdft%first_iteration)
ALLOCATE (coefficients(natom))
2422 DO i = 1, cdft_control%natoms
2423 catom(i) = cdft_control%atoms(i)
2424 IF (cdft_control%save_pot .OR. &
2425 cdft_control%becke_control%cavity_confine .OR. &
2426 cdft_control%becke_control%should_skip .OR. &
2427 mixed_cdft%first_iteration)
THEN
2428 is_constraint(catom(i)) = .true.
2430 IF (in_memory .OR. mixed_cdft%first_iteration)
THEN
2431 coefficients(catom(i)) = cdft_control%group(1)%coeff(i)
2434 CALL pw_env_get(pw_env=mixed_cdft%pw_env, auxbas_pw_pool=auxbas_pw_pool)
2435 bo = auxbas_pw_pool%pw_grid%bounds_local
2436 np = auxbas_pw_pool%pw_grid%npts
2437 dr = auxbas_pw_pool%pw_grid%dr
2438 shift = -real(
modulo(np, 2),
dp)*dr/2.0_dp
2439 IF (store_vectors)
THEN
2440 IF (in_memory)
ALLOCATE (pair_dist_vecs(3, natom, natom))
2441 ALLOCATE (position_vecs(3, natom))
2444 cell_v(i) = cell%hmat(i, i)
2446 ALLOCATE (r12(natom, natom))
2447 DO iatom = 1, natom - 1
2448 DO jatom = iatom + 1, natom
2449 r = particle_set(iatom)%r
2450 r1 = particle_set(jatom)%r
2452 r(i) =
modulo(r(i), cell%hmat(i, i)) - cell%hmat(i, i)/2._dp
2453 r1(i) =
modulo(r1(i), cell%hmat(i, i)) - cell%hmat(i, i)/2._dp
2455 dist_vec = (r - r1) - anint((r - r1)/cell_v)*cell_v
2456 IF (store_vectors)
THEN
2457 position_vecs(:, iatom) = r(:)
2458 IF (iatom == 1 .AND. jatom == natom) position_vecs(:, jatom) = r1(:)
2460 pair_dist_vecs(:, iatom, jatom) = dist_vec(:)
2461 pair_dist_vecs(:, jatom, iatom) = -dist_vec(:)
2464 r12(iatom, jatom) = norm2(dist_vec)
2465 r12(jatom, iatom) = r12(iatom, jatom)
2469 ircov = cdft_control%becke_control%radii(ikind)
2472 jrcov = cdft_control%becke_control%radii(ikind)
2473 IF (ircov /= jrcov)
THEN
2475 uij = (chi - 1.0_dp)/(chi + 1.0_dp)
2476 cdft_control%becke_control%aij(iatom, jatom) = uij/(uij**2 - 1.0_dp)
2477 IF (cdft_control%becke_control%aij(iatom, jatom) &
2479 cdft_control%becke_control%aij(iatom, jatom) = 0.5_dp
2480 ELSE IF (cdft_control%becke_control%aij(iatom, jatom) &
2482 cdft_control%becke_control%aij(iatom, jatom) = -0.5_dp
2485 cdft_control%becke_control%aij(iatom, jatom) = 0.0_dp
2487 cdft_control%becke_control%aij(jatom, iatom) = &
2488 -cdft_control%becke_control%aij(iatom, jatom)
2493 IF (mixed_cdft%first_iteration)
THEN
2496 IF (iounit > 0)
THEN
2497 WRITE (iounit,
'(/,T3,A,T66)') &
2498 '-------------------------- Becke atomic parameters ---------------------------'
2499 IF (cdft_control%becke_control%adjust)
THEN
2500 WRITE (iounit,
'(T3,A,A)') &
2501 'Atom Element Coefficient',
' Cutoff (angstrom) CDFT Radius (angstrom)'
2504 element_symbol=element_symbol, &
2507 IF (is_constraint(iatom))
THEN
2508 coef = coefficients(iatom)
2512 WRITE (iounit,
"(i6,T14,A2,T22,F8.3,T44,F8.3,T73,F8.3)") &
2513 iatom, adjustr(element_symbol), coef, &
2518 WRITE (iounit,
'(T3,A,A)') &
2519 'Atom Element Coefficient',
' Cutoff (angstrom)'
2522 element_symbol=element_symbol)
2523 IF (is_constraint(iatom))
THEN
2524 coef = coefficients(iatom)
2528 WRITE (iounit,
"(i6,T14,A2,T22,F8.3,T44,F8.3)") &
2529 iatom, adjustr(element_symbol), coef, &
2533 WRITE (iounit,
'(T3,A)') &
2534 '------------------------------------------------------------------------------'
2537 "MIXED%MIXED_CDFT%PRINT%PROGRAM_RUN_INFO")
2538 mixed_cdft%first_iteration = .false.
2541 IF (cdft_control%becke_control%cavity_confine)
THEN
2542 cpassert(
ASSOCIATED(mixed_cdft%qs_kind_set))
2543 cavity_env => cdft_control%becke_control%cavity_env
2544 qs_kind_set => mixed_cdft%qs_kind_set
2545 CALL cp_subsys_get(subsys_mix, atomic_kind_set=atomic_kind_set)
2546 nkind =
SIZE(qs_kind_set)
2547 IF (.NOT.
ASSOCIATED(cavity_env%kind_shape_fn))
THEN
2548 IF (
ASSOCIATED(cdft_control%becke_control%radii))
THEN
2549 ALLOCATE (radii_list(
SIZE(cdft_control%becke_control%radii)))
2550 DO ikind = 1,
SIZE(cdft_control%becke_control%radii)
2551 IF (cavity_env%use_bohr)
THEN
2552 radii_list(ikind) = cdft_control%becke_control%radii(ikind)
2554 radii_list(ikind) =
cp_unit_from_cp2k(cdft_control%becke_control%radii(ikind),
"angstrom")
2559 radius=cdft_control%becke_control%rcavity, &
2560 radii_list=radii_list)
2561 IF (
ASSOCIATED(radii_list))
THEN
2562 DEALLOCATE (radii_list)
2566 CALL pw_env_get(pw_env=mixed_cdft%pw_env, auxbas_rs_grid=rs_cavity, &
2567 auxbas_pw_pool=auxbas_pw_pool)
2570 ALLOCATE (pab(1, 1))
2573 DO ikind = 1,
SIZE(atomic_kind_set)
2574 numexp = cavity_env%kind_shape_fn(ikind)%numexp
2575 IF (numexp <= 0) cycle
2576 CALL get_atomic_kind(atomic_kind_set(ikind), natom=katom, atom_list=atom_list)
2577 ALLOCATE (cores(katom))
2579 alpha = cavity_env%kind_shape_fn(ikind)%zet(iex)
2580 coef = cavity_env%kind_shape_fn(ikind)%coef(iex)
2584 IF (rs_cavity%desc%parallel .AND. .NOT. rs_cavity%desc%distributed)
THEN
2586 IF (
modulo(iatom, rs_cavity%desc%group_size) == rs_cavity%desc%my_pos)
THEN
2597 atom_a = atom_list(iatom)
2599 IF (store_vectors)
THEN
2600 ra(:) = position_vecs(:, atom_a) + cell_v(:)/2._dp
2602 ra(:) =
pbc(particle_set(atom_a)%r, cell)
2604 IF (is_constraint(atom_a))
THEN
2606 ra=ra, rb=ra, rp=ra, &
2607 zetp=alpha, eps=mixed_cdft%eps_rho_rspace, &
2608 pab=pab, o1=0, o2=0, &
2609 prefactor=1.0_dp, cutoff=0.0_dp)
2612 [0.0_dp, 0.0_dp, 0.0_dp], 1.0_dp, pab, 0, 0, &
2615 use_subpatch=.true., &
2623 CALL auxbas_pw_pool%create_pw(cdft_control%becke_control%cavity)
2624 CALL transfer_rs2pw(rs_cavity, cdft_control%becke_control%cavity)
2625 CALL hfun_zero(cdft_control%becke_control%cavity%array, &
2626 cdft_control%becke_control%eps_cavity, &
2627 just_zero=.false., bounds=bounds, work=my_work)
2628 IF (bounds(2) < bo(2, 3))
THEN
2629 bounds(2) = bounds(2) - 1
2631 bounds(2) = bo(2, 3)
2633 IF (bounds(1) > bo(1, 3))
THEN
2637 bounds(1) = bounds(1) + 1
2639 bounds(1) = bo(1, 3)
2641 IF (bounds(1) > bounds(2))
THEN
2644 my_work_size = (bounds(2) - bounds(1) + 1)
2645 IF (mixed_cdft%is_pencil .OR. mixed_cdft%is_special)
THEN
2646 my_work_size = my_work_size*(bo(2, 2) - bo(1, 2) + 1)
2648 my_work_size = my_work_size*(bo(2, 1) - bo(1, 1) + 1)
2651 cdft_control%becke_control%confine_bounds = bounds
2652 IF (cdft_control%becke_control%print_cavity)
THEN
2653 CALL hfun_zero(cdft_control%becke_control%cavity%array, &
2654 cdft_control%becke_control%eps_cavity, just_zero=.true.)
2656 ALLOCATE (stride(3))
2660 middle_name=
"BECKE_CAVITY", &
2661 extension=
".cube", file_position=
"REWIND", &
2662 log_filename=.false., mpi_io=mpi_io)
2663 IF (force_env%para_env%is_source() .AND. unit_nr < 1)
THEN
2664 CALL cp_abort(__location__, &
2665 "Please turn on PROGRAM_RUN_INFO to print cavity")
2668 unit_nr,
"CAVITY", particles=particles, &
2669 stride=stride, mpi_io=mpi_io)
2675 IF (cdft_control%becke_control%cavity_confine)
THEN
2676 bo_conf(:, 3) = cdft_control%becke_control%confine_bounds
2679 IF (mixed_cdft%dlb)
THEN
2680 CALL mixed_becke_constraint_dlb(force_env, mixed_cdft, my_work, &
2681 my_work_size, natom, bo, bo_conf)
2685 IF (mixed_cdft%dlb)
THEN
2686 IF (mixed_cdft%dlb_control%send_work .AND. .NOT. mixed_cdft%is_special)
THEN
2687 offset_dlb = sum(mixed_cdft%dlb_control%target_list(2, :))
2690 IF (cdft_control%becke_control%cavity_confine)
THEN
2692 IF (mixed_cdft%is_special)
THEN
2693 ALLOCATE (mixed_cdft%sendbuff(
SIZE(mixed_cdft%dest_list)))
2694 DO i = 1,
SIZE(mixed_cdft%dest_list)
2695 ALLOCATE (mixed_cdft%sendbuff(i)%cavity(mixed_cdft%dest_list_bo(1, i):mixed_cdft%dest_list_bo(2, i), &
2696 bo(1, 2):bo(2, 2), bo_conf(1, 3):bo_conf(2, 3)))
2697 mixed_cdft%sendbuff(i)%cavity = cdft_control%becke_control%cavity%array(mixed_cdft%dest_list_bo(1, i): &
2698 mixed_cdft%dest_list_bo(2, i), &
2699 bo(1, 2):bo(2, 2), &
2700 bo_conf(1, 3):bo_conf(2, 3))
2702 ELSE IF (mixed_cdft%is_pencil)
THEN
2703 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)))
2704 mixed_cdft%cavity = cdft_control%becke_control%cavity%array(bo(1, 1) + offset_dlb:bo(2, 1), &
2705 bo(1, 2):bo(2, 2), &
2706 bo_conf(1, 3):bo_conf(2, 3))
2708 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)))
2709 mixed_cdft%cavity = cdft_control%becke_control%cavity%array(bo(1, 1):bo(2, 1), &
2710 bo(1, 2) + offset_dlb:bo(2, 2), &
2711 bo_conf(1, 3):bo_conf(2, 3))
2713 CALL auxbas_pw_pool%give_back_pw(cdft_control%becke_control%cavity)
2715 IF (mixed_cdft%is_special)
THEN
2716 DO i = 1,
SIZE(mixed_cdft%dest_list)
2717 ALLOCATE (mixed_cdft%sendbuff(i)%weight(mixed_cdft%dest_list_bo(1, i):mixed_cdft%dest_list_bo(2, i), &
2718 bo(1, 2):bo(2, 2), bo_conf(1, 3):bo_conf(2, 3)))
2719 mixed_cdft%sendbuff(i)%weight = 0.0_dp
2721 ELSE IF (mixed_cdft%is_pencil)
THEN
2722 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)))
2723 mixed_cdft%weight = 0.0_dp
2725 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)))
2726 mixed_cdft%weight = 0.0_dp
2729 IF (mixed_cdft%is_special)
THEN
2730 DO i = 1,
SIZE(mixed_cdft%dest_list)
2731 ALLOCATE (mixed_cdft%sendbuff(i)%gradients(3*natom, mixed_cdft%dest_list_bo(1, i): &
2732 mixed_cdft%dest_list_bo(2, i), &
2733 bo(1, 2):bo(2, 2), &
2734 bo_conf(1, 3):bo_conf(2, 3)))
2735 mixed_cdft%sendbuff(i)%gradients = 0.0_dp
2737 ELSE IF (mixed_cdft%is_pencil)
THEN
2738 ALLOCATE (cdft_control%group(1)%gradients(3*natom, bo(1, 1) + offset_dlb:bo(2, 1), &
2739 bo(1, 2):bo(2, 2), &
2740 bo_conf(1, 3):bo_conf(2, 3)))
2741 cdft_control%group(1)%gradients = 0.0_dp
2743 ALLOCATE (cdft_control%group(1)%gradients(3*natom, bo(1, 1):bo(2, 1), &
2744 bo(1, 2) + offset_dlb:bo(2, 2), &
2745 bo_conf(1, 3):bo_conf(2, 3)))
2746 cdft_control%group(1)%gradients = 0.0_dp
2750 CALL timestop(handle)
2752 END SUBROUTINE mixed_becke_constraint_init
2767 SUBROUTINE mixed_becke_constraint_dlb(force_env, mixed_cdft, my_work, &
2768 my_work_size, natom, bo, bo_conf)
2771 INTEGER,
INTENT(IN) :: my_work, my_work_size, natom
2772 INTEGER,
DIMENSION(2, 3) :: bo, bo_conf
2774 CHARACTER(len=*),
PARAMETER :: routinen =
'mixed_becke_constraint_dlb'
2775 INTEGER,
PARAMETER :: should_deallocate = 7000, &
2776 uninitialized = -7000
2778 CHARACTER(len=2) :: dummy
2779 INTEGER :: actually_sent, exhausted_work, handle, i, ind, iounit, ispecial, j, max_targets, &
2780 more_work, my_pos, my_special_work, my_target, no_overloaded, no_underloaded, nsend, &
2781 nsend_limit, nsend_max, offset, offset_proc, offset_special, send_total, tags(2)
2782 INTEGER,
DIMENSION(:),
POINTER :: buffsize, cumulative_work, expected_work, load_imbalance, &
2783 nrecv, nsend_proc, sendbuffer, should_warn, tmp, work_index, work_size
2784 INTEGER,
DIMENSION(:, :),
POINTER :: targets, tmp_bo
2785 LOGICAL :: consistent
2786 LOGICAL,
DIMENSION(:),
POINTER :: mask_recv, mask_send, touched
2787 REAL(kind=
dp) :: average_work, load_scale, &
2788 very_overloaded, work_factor
2789 REAL(kind=
dp),
DIMENSION(:, :, :),
POINTER :: cavity
2790 TYPE(buffers_bi),
DIMENSION(:),
POINTER :: recvbuffer, sbuff
2798 CALL timeset(routinen, handle)
2799 mixed_cdft%dlb_control%recv_work = .false.
2800 mixed_cdft%dlb_control%send_work = .false.
2801 NULLIFY (expected_work, work_index, load_imbalance, work_size, &
2802 cumulative_work, sendbuffer, buffsize, req_recv, req_total, &
2803 tmp, nrecv, nsend_proc, targets, tmp_bo, touched, &
2804 mask_recv, mask_send, cavity, recvbuffer, sbuff, force_env_section, &
2805 print_section, cdft_control)
2806 CALL force_env_get(force_env=force_env, force_env_section=force_env_section)
2809 cdft_control => mixed_cdft%cdft_control
2814 load_scale = mixed_cdft%dlb_control%load_scale
2815 very_overloaded = mixed_cdft%dlb_control%very_overloaded
2816 more_work = mixed_cdft%dlb_control%more_work
2818 work_factor = 0.8_dp
2820 IF (mixed_cdft%is_special)
THEN
2821 DEALLOCATE (mixed_cdft%dest_list, mixed_cdft%dest_list_bo, &
2822 mixed_cdft%source_list, mixed_cdft%source_list_bo)
2823 ALLOCATE (mixed_cdft%dest_list(
SIZE(mixed_cdft%dest_list_save)), &
2824 mixed_cdft%dest_list_bo(
SIZE(mixed_cdft%dest_bo_save, 1),
SIZE(mixed_cdft%dest_bo_save, 2)), &
2825 mixed_cdft%source_list(
SIZE(mixed_cdft%source_list_save)), &
2826 mixed_cdft%source_list_bo(
SIZE(mixed_cdft%source_bo_save, 1),
SIZE(mixed_cdft%source_bo_save, 2)))
2827 mixed_cdft%dest_list = mixed_cdft%dest_list_save
2828 mixed_cdft%source_list = mixed_cdft%source_list_save
2829 mixed_cdft%dest_list_bo = mixed_cdft%dest_bo_save
2830 mixed_cdft%source_list_bo = mixed_cdft%source_bo_save
2832 ALLOCATE (mixed_cdft%dlb_control%expected_work(force_env%para_env%num_pe), &
2833 expected_work(force_env%para_env%num_pe), &
2834 work_size(force_env%para_env%num_pe))
2835 IF (debug_this_module)
THEN
2836 ALLOCATE (should_warn(force_env%para_env%num_pe))
2840 expected_work(force_env%para_env%mepos + 1) = my_work
2842 work_size(force_env%para_env%mepos + 1) = my_work_size
2843 IF (
ASSOCIATED(mixed_cdft%dlb_control%prediction_error))
THEN
2844 IF (mixed_cdft%is_pencil .OR. mixed_cdft%is_special)
THEN
2845 work_size(force_env%para_env%mepos + 1) = work_size(force_env%para_env%mepos + 1) - &
2846 nint(real(mixed_cdft%dlb_control% &
2847 prediction_error(force_env%para_env%mepos + 1),
dp)/ &
2848 REAL(bo(2, 1) - bo(1, 1) + 1,
dp))
2850 work_size(force_env%para_env%mepos + 1) = work_size(force_env%para_env%mepos + 1) - &
2851 nint(real(mixed_cdft%dlb_control% &
2852 prediction_error(force_env%para_env%mepos + 1),
dp)/ &
2853 REAL(bo(2, 2) - bo(1, 2) + 1,
dp))
2856 CALL force_env%para_env%sum(expected_work)
2857 CALL force_env%para_env%sum(work_size)
2859 mixed_cdft%dlb_control%expected_work = expected_work
2861 IF (
ASSOCIATED(mixed_cdft%dlb_control%prediction_error))
THEN
2862 expected_work = expected_work - mixed_cdft%dlb_control%prediction_error
2865 average_work = real(sum(expected_work),
dp)/real(force_env%para_env%num_pe,
dp)
2866 ALLOCATE (work_index(force_env%para_env%num_pe), &
2867 load_imbalance(force_env%para_env%num_pe), &
2868 targets(2, force_env%para_env%num_pe))
2869 load_imbalance = expected_work - nint(average_work)
2874 DO i = 1, force_env%para_env%num_pe
2875 IF (load_imbalance(i) > 0)
THEN
2876 no_overloaded = no_overloaded + 1
2878 IF (expected_work(i) > nint(very_overloaded*average_work))
THEN
2879 load_imbalance(i) = (ceiling(real(load_imbalance(i),
dp)/real(work_size(i),
dp)) + more_work)*work_size(i)
2881 load_imbalance(i) = ceiling(real(load_imbalance(i),
dp)/real(work_size(i),
dp))*work_size(i)
2886 load_imbalance(i) = nint(load_imbalance(i)*load_scale)
2887 no_underloaded = no_underloaded + 1
2890 CALL sort(expected_work, force_env%para_env%num_pe, indices=work_index)
2893 IF (load_imbalance(force_env%para_env%mepos + 1) > 0)
THEN
2895 mixed_cdft%dlb_control%send_work = .true.
2897 ALLOCATE (cumulative_work(force_env%para_env%num_pe))
2899 DO i = force_env%para_env%num_pe, force_env%para_env%num_pe - no_overloaded + 1, -1
2900 IF (work_index(i) == force_env%para_env%mepos + 1)
THEN
2903 offset = offset + load_imbalance(work_index(i))
2904 IF (i == force_env%para_env%num_pe)
THEN
2905 cumulative_work(i) = load_imbalance(work_index(i))
2907 cumulative_work(i) = cumulative_work(i + 1) + load_imbalance(work_index(i))
2912 j = force_env%para_env%num_pe
2913 nsend_max = load_imbalance(work_index(j))/work_size(work_index(j))
2916 DO i = 1, no_underloaded
2917 IF (my_pos == force_env%para_env%num_pe)
EXIT
2918 nsend = -load_imbalance(work_index(i))/work_size(work_index(j))
2919 IF (nsend < 1) nsend = 1
2920 nsend_max = nsend_max - nsend
2921 IF (nsend_max < 0) nsend = nsend + nsend_max
2922 exhausted_work = exhausted_work + nsend*work_size(work_index(j))
2923 offset = offset - nsend*work_size(work_index(j))
2924 IF (offset < 0)
EXIT
2925 IF (exhausted_work == cumulative_work(j))
THEN
2927 nsend_max = load_imbalance(work_index(j))/work_size(work_index(j))
2932 IF (i > no_underloaded)
THEN
2936 DEALLOCATE (cumulative_work)
2938 nsend_max = load_imbalance(force_env%para_env%mepos + 1)/work_size(force_env%para_env%mepos + 1)
2940 IF (mixed_cdft%is_pencil .OR. mixed_cdft%is_special)
THEN
2941 nsend_limit = bo(2, 1) - bo(1, 1) + 1
2943 nsend_limit = bo(2, 2) - bo(1, 2) + 1
2945 IF (.NOT. mixed_cdft%is_special)
THEN
2946 ALLOCATE (mixed_cdft%dlb_control%target_list(3, max_targets))
2948 ALLOCATE (mixed_cdft%dlb_control%target_list(3 + 2*
SIZE(mixed_cdft%dest_list), max_targets))
2949 ALLOCATE (touched(
SIZE(mixed_cdft%dest_list)))
2952 mixed_cdft%dlb_control%target_list = uninitialized
2956 targets(1, my_pos) = my_target
2960 nsend = -load_imbalance(work_index(my_target))/work_size(force_env%para_env%mepos + 1)
2961 IF (nsend < 1) nsend = 1
2963 IF (nsend > nint(work_factor*nsend_limit - send_total))
THEN
2964 nsend = nint(work_factor*nsend_limit - send_total)
2965 IF (debug_this_module)
THEN
2966 should_warn(force_env%para_env%mepos + 1) = 1
2969 mixed_cdft%dlb_control%target_list(1, i) = work_index(my_target) - 1
2970 IF (mixed_cdft%is_special)
THEN
2971 mixed_cdft%dlb_control%target_list(2, i) = 0
2972 actually_sent = nsend
2973 DO j = ispecial,
SIZE(mixed_cdft%dest_list)
2974 mixed_cdft%dlb_control%target_list(2, i) = mixed_cdft%dlb_control%target_list(2, i) + 1
2976 IF (nsend < mixed_cdft%dest_list_bo(2, j) - mixed_cdft%dest_list_bo(1, j) + 1)
THEN
2977 mixed_cdft%dlb_control%target_list(3 + 2*j - 1, i) = mixed_cdft%dest_list_bo(1, j)
2978 mixed_cdft%dlb_control%target_list(3 + 2*j, i) = mixed_cdft%dest_list_bo(1, j) + nsend - 1
2979 mixed_cdft%dest_list_bo(1, j) = mixed_cdft%dest_list_bo(1, j) + nsend
2983 mixed_cdft%dlb_control%target_list(3 + 2*j - 1, i) = mixed_cdft%dest_list_bo(1, j)
2984 mixed_cdft%dlb_control%target_list(3 + 2*j, i) = mixed_cdft%dest_list_bo(2, j)
2985 nsend = nsend - (mixed_cdft%dest_list_bo(2, j) - mixed_cdft%dest_list_bo(1, j) + 1)
2986 mixed_cdft%dest_list_bo(1:2, j) = should_deallocate
2988 IF (nsend <= 0)
EXIT
2990 IF (mixed_cdft%dest_list_bo(1, ispecial) == should_deallocate) ispecial = j + 1
2991 actually_sent = actually_sent - nsend
2992 nsend_max = nsend_max - actually_sent
2993 send_total = send_total + actually_sent
2995 mixed_cdft%dlb_control%target_list(2, i) = nsend
2996 nsend_max = nsend_max - nsend
2997 send_total = send_total + nsend
2999 IF (nsend_max < 0) nsend_max = 0
3000 IF (nsend_max == 0)
EXIT
3001 IF (my_target /= no_underloaded)
THEN
3002 my_target = my_target + 1
3005 mixed_cdft%dlb_control%target_list(2, i) = mixed_cdft%dlb_control%target_list(2, i) + nsend_max
3010 IF (i > max_targets)
THEN
3011 CALL cp_abort(__location__, &
3012 "Load balancing error: increase max_targets")
3015 IF (.NOT. mixed_cdft%is_special)
THEN
3016 CALL reallocate(mixed_cdft%dlb_control%target_list, 1, 3, 1, i)
3018 CALL reallocate(mixed_cdft%dlb_control%target_list, 1, 3 + 2*
SIZE(mixed_cdft%dest_list), 1, i)
3020 targets(2, my_pos) = my_target
3022 IF (.NOT. mixed_cdft%is_special)
THEN
3023 IF (send_total > nint(work_factor*nsend_limit)) send_total = nint(work_factor*nsend_limit) - 1
3024 nsend = nint(real(send_total,
dp)/real(
SIZE(mixed_cdft%dlb_control%target_list, 2),
dp))
3025 mixed_cdft%dlb_control%target_list(2, :) = nsend
3028 DO i = 1, no_underloaded
3029 IF (work_index(i) == force_env%para_env%mepos + 1)
EXIT
3033 CALL force_env%para_env%sum(targets)
3034 IF (debug_this_module)
THEN
3035 CALL force_env%para_env%sum(should_warn)
3036 IF (any(should_warn == 1))
THEN
3037 CALL cp_warn(__location__, &
3038 "MIXED_CDFT DLB: Attempted to redistribute more array"// &
3039 " slices than actually available. Leaving a fraction of the total"// &
3040 " slices on the overloaded processor. Perhaps you have set LOAD_SCALE too high?")
3042 DEALLOCATE (should_warn)
3045 IF (force_env%para_env%is_source())
THEN
3047 DO i = force_env%para_env%num_pe - 1, force_env%para_env%num_pe - no_overloaded + 1, -1
3048 IF (targets(1, i) > no_underloaded) consistent = .false.
3049 IF (targets(1, i) > targets(2, i + 1))
THEN
3052 consistent = .false.
3055 IF (.NOT. consistent)
THEN
3056 IF (debug_this_module .AND. iounit > 0)
THEN
3057 DO i = force_env%para_env%num_pe - 1, force_env%para_env%num_pe - no_overloaded + 1, -1
3058 WRITE (iounit,
'(A,I8,I8,I8,I8,I8)') &
3059 'load balancing info', load_imbalance(i), work_index(i), &
3060 work_size(i), targets(1, i), targets(2, i)
3063 CALL cp_abort(__location__, &
3064 "Load balancing error: too much data to redistribute."// &
3065 " Increase LOAD_SCALE or change the number of processors."// &
3066 " If the confinement cavity occupies a large volume relative"// &
3067 " to the total system volume, it might be worth disabling DLB.")
3071 IF (my_pos <= no_underloaded)
THEN
3072 DO i = force_env%para_env%num_pe, force_env%para_env%num_pe - no_overloaded + 1, -1
3073 IF (targets(1, i) <= my_pos .AND. targets(2, i) >= my_pos)
THEN
3074 mixed_cdft%dlb_control%recv_work = .true.
3075 mixed_cdft%dlb_control%my_source = work_index(i) - 1
3079 IF (mixed_cdft%dlb_control%recv_work)
THEN
3080 IF (.NOT. mixed_cdft%is_special)
THEN
3081 ALLOCATE (mixed_cdft%dlb_control%bo(12))
3082 CALL force_env%para_env%irecv(msgout=mixed_cdft%dlb_control%bo, source=mixed_cdft%dlb_control%my_source, &
3085 mixed_cdft%dlb_control%my_dest_repl = [mixed_cdft%dlb_control%bo(11), mixed_cdft%dlb_control%bo(12)]
3086 mixed_cdft%dlb_control%dest_tags_repl = [mixed_cdft%dlb_control%bo(9), mixed_cdft%dlb_control%bo(10)]
3087 ALLOCATE (mixed_cdft%dlb_control%cavity(mixed_cdft%dlb_control%bo(1):mixed_cdft%dlb_control%bo(2), &
3088 mixed_cdft%dlb_control%bo(3):mixed_cdft%dlb_control%bo(4), &
3089 mixed_cdft%dlb_control%bo(7):mixed_cdft%dlb_control%bo(8)))
3090 ALLOCATE (mixed_cdft%dlb_control%weight(mixed_cdft%dlb_control%bo(1):mixed_cdft%dlb_control%bo(2), &
3091 mixed_cdft%dlb_control%bo(3):mixed_cdft%dlb_control%bo(4), &
3092 mixed_cdft%dlb_control%bo(7):mixed_cdft%dlb_control%bo(8)))
3093 ALLOCATE (mixed_cdft%dlb_control%gradients(3*natom, &
3094 mixed_cdft%dlb_control%bo(1):mixed_cdft%dlb_control%bo(2), &
3095 mixed_cdft%dlb_control%bo(3):mixed_cdft%dlb_control%bo(4), &
3096 mixed_cdft%dlb_control%bo(7):mixed_cdft%dlb_control%bo(8)))
3097 mixed_cdft%dlb_control%gradients = 0.0_dp
3098 mixed_cdft%dlb_control%weight = 0.0_dp
3099 CALL force_env%para_env%irecv(msgout=mixed_cdft%dlb_control%cavity, source=mixed_cdft%dlb_control%my_source, &
3102 DEALLOCATE (mixed_cdft%dlb_control%bo)
3104 ALLOCATE (buffsize(1))
3105 CALL force_env%para_env%irecv(msgout=buffsize, source=mixed_cdft%dlb_control%my_source, &
3108 ALLOCATE (mixed_cdft%dlb_control%bo(12*buffsize(1)))
3109 CALL force_env%para_env%irecv(msgout=mixed_cdft%dlb_control%bo, source=mixed_cdft%dlb_control%my_source, &
3111 ALLOCATE (mixed_cdft%dlb_control%sendbuff(buffsize(1)))
3112 ALLOCATE (req_recv(buffsize(1)))
3113 DEALLOCATE (buffsize)
3115 DO j = 1,
SIZE(mixed_cdft%dlb_control%sendbuff)
3116 ALLOCATE (mixed_cdft%dlb_control%sendbuff(j)%cavity(mixed_cdft%dlb_control%bo(12*(j - 1) + 1): &
3117 mixed_cdft%dlb_control%bo(12*(j - 1) + 2), &
3118 mixed_cdft%dlb_control%bo(12*(j - 1) + 3): &
3119 mixed_cdft%dlb_control%bo(12*(j - 1) + 4), &
3120 mixed_cdft%dlb_control%bo(12*(j - 1) + 7): &
3121 mixed_cdft%dlb_control%bo(12*(j - 1) + 8)))
3122 CALL force_env%para_env%irecv(msgout=mixed_cdft%dlb_control%sendbuff(j)%cavity, &
3123 source=mixed_cdft%dlb_control%my_source, &
3124 request=req_recv(j))
3125 ALLOCATE (mixed_cdft%dlb_control%sendbuff(j)%weight(mixed_cdft%dlb_control%bo(12*(j - 1) + 1): &
3126 mixed_cdft%dlb_control%bo(12*(j - 1) + 2), &
3127 mixed_cdft%dlb_control%bo(12*(j - 1) + 3): &
3128 mixed_cdft%dlb_control%bo(12*(j - 1) + 4), &
3129 mixed_cdft%dlb_control%bo(12*(j - 1) + 7): &
3130 mixed_cdft%dlb_control%bo(12*(j - 1) + 8)))
3131 ALLOCATE (mixed_cdft%dlb_control%sendbuff(j)%gradients(3*natom, &
3132 mixed_cdft%dlb_control%bo(12*(j - 1) + 1): &
3133 mixed_cdft%dlb_control%bo(12*(j - 1) + 2), &
3134 mixed_cdft%dlb_control%bo(12*(j - 1) + 3): &
3135 mixed_cdft%dlb_control%bo(12*(j - 1) + 4), &
3136 mixed_cdft%dlb_control%bo(12*(j - 1) + 7): &
3137 mixed_cdft%dlb_control%bo(12*(j - 1) + 8)))
3138 mixed_cdft%dlb_control%sendbuff(j)%weight = 0.0_dp
3139 mixed_cdft%dlb_control%sendbuff(j)%gradients = 0.0_dp
3140 mixed_cdft%dlb_control%sendbuff(j)%tag = [mixed_cdft%dlb_control%bo(12*(j - 1) + 9), &
3141 mixed_cdft%dlb_control%bo(12*(j - 1) + 10)]
3142 mixed_cdft%dlb_control%sendbuff(j)%rank = [mixed_cdft%dlb_control%bo(12*(j - 1) + 11), &
3143 mixed_cdft%dlb_control%bo(12*(j - 1) + 12)]
3146 DEALLOCATE (req_recv)
3150 IF (.NOT. mixed_cdft%is_special)
THEN
3152 ALLOCATE (sendbuffer(12))
3154 DO i = 1,
SIZE(mixed_cdft%dlb_control%target_list, 2)
3155 tags = [(i - 1)*3 + 1 + force_env%para_env%mepos*6*max_targets, &
3156 (i - 1)*3 + 1 + 3*max_targets + force_env%para_env%mepos*6*max_targets]
3157 mixed_cdft%dlb_control%target_list(3, i) = tags(1)
3158 IF (mixed_cdft%is_pencil)
THEN
3159 sendbuffer = [bo_conf(1, 1) + offset, &
3160 bo_conf(1, 1) + offset + (mixed_cdft%dlb_control%target_list(2, i) - 1), &
3161 bo_conf(1, 2), bo_conf(2, 2), bo(1, 3), bo(2, 3), bo_conf(1, 3), bo_conf(2, 3), &
3162 tags(1), tags(2), mixed_cdft%dest_list(1), mixed_cdft%dest_list(2)]
3164 sendbuffer = [bo_conf(1, 1), bo_conf(2, 1), &
3165 bo_conf(1, 2) + offset, &
3166 bo_conf(1, 2) + offset + (mixed_cdft%dlb_control%target_list(2, i) - 1), &
3167 bo(1, 3), bo(2, 3), bo_conf(1, 3), bo_conf(2, 3), tags(1), tags(2), &
3168 mixed_cdft%dest_list(1), mixed_cdft%dest_list(2)]
3170 send_total = send_total + mixed_cdft%dlb_control%target_list(2, i) - 1
3171 CALL force_env%para_env%isend(msgin=sendbuffer, dest=mixed_cdft%dlb_control%target_list(1, i), &
3174 IF (mixed_cdft%is_pencil)
THEN
3175 ALLOCATE (cavity(bo_conf(1, 1) + offset: &
3176 bo_conf(1, 1) + offset + (mixed_cdft%dlb_control%target_list(2, i) - 1), &
3177 bo_conf(1, 2):bo_conf(2, 2), bo_conf(1, 3):bo_conf(2, 3)))
3178 cavity = cdft_control%becke_control%cavity%array(bo_conf(1, 1) + offset: &
3179 bo_conf(1, 1) + offset + &
3180 (mixed_cdft%dlb_control%target_list(2, i) - 1), &
3181 bo_conf(1, 2):bo_conf(2, 2), &
3182 bo_conf(1, 3):bo_conf(2, 3))
3184 ALLOCATE (cavity(bo_conf(1, 1):bo_conf(2, 1), &
3185 bo_conf(1, 2) + offset: &
3186 bo_conf(1, 2) + offset + (mixed_cdft%dlb_control%target_list(2, i) - 1), &
3187 bo_conf(1, 3):bo_conf(2, 3)))
3188 cavity = cdft_control%becke_control%cavity%array(bo_conf(1, 1):bo_conf(2, 1), &
3189 bo_conf(1, 2) + offset: &
3190 bo_conf(1, 2) + offset + &
3191 (mixed_cdft%dlb_control%target_list(2, i) - 1), &
3192 bo_conf(1, 3):bo_conf(2, 3))
3194 CALL force_env%para_env%isend(msgin=cavity, &
3195 dest=mixed_cdft%dlb_control%target_list(1, i), &
3198 offset = offset + mixed_cdft%dlb_control%target_list(2, i)
3201 IF (mixed_cdft%is_pencil)
THEN
3202 mixed_cdft%dlb_control%distributed(1) = bo_conf(1, 1)
3203 mixed_cdft%dlb_control%distributed(2) = bo_conf(1, 1) + offset - 1
3205 mixed_cdft%dlb_control%distributed(1) = bo_conf(1, 2)
3206 mixed_cdft%dlb_control%distributed(2) = bo_conf(1, 2) + offset - 1
3208 DEALLOCATE (sendbuffer)
3210 ALLOCATE (buffsize(1))
3211 DO i = 1,
SIZE(mixed_cdft%dlb_control%target_list, 2)
3212 buffsize = mixed_cdft%dlb_control%target_list(2, i)
3214 tags = [(i - 1)*3 + 1 + force_env%para_env%mepos*6*max_targets, &
3215 (i - 1)*3 + 1 + 3*max_targets + force_env%para_env%mepos*6*max_targets]
3216 DO j = 4,
SIZE(mixed_cdft%dlb_control%target_list, 1)
3217 IF (mixed_cdft%dlb_control%target_list(j, i) > uninitialized)
EXIT
3220 offset_proc = j - 4 - (j - 4)/2
3221 CALL force_env%para_env%isend(msgin=buffsize, &
3222 dest=mixed_cdft%dlb_control%target_list(1, i), &
3225 ALLOCATE (sendbuffer(12*buffsize(1)))
3226 DO j = 1, buffsize(1)
3227 sendbuffer(12*(j - 1) + 1:12*(j - 1) + 12) = [mixed_cdft%dlb_control%target_list(offset_special + 2*(j - 1), i), &
3228 mixed_cdft%dlb_control%target_list(offset_special + 2*j - 1, i), &
3229 bo_conf(1, 2), bo_conf(2, 2), bo(1, 3), bo(2, 3), &
3230 bo_conf(1, 3), bo_conf(2, 3), tags(1), tags(2), &
3231 mixed_cdft%dest_list(j + offset_proc), &
3232 mixed_cdft%dest_list(j + offset_proc) + force_env%para_env%num_pe/2]
3234 CALL force_env%para_env%isend(msgin=sendbuffer, &
3235 dest=mixed_cdft%dlb_control%target_list(1, i), &
3238 DEALLOCATE (sendbuffer)
3239 DO j = 1, buffsize(1)
3240 ALLOCATE (cavity(mixed_cdft%dlb_control%target_list(offset_special + 2*(j - 1), i): &
3241 mixed_cdft%dlb_control%target_list(offset_special + 2*j - 1, i), &
3242 bo_conf(1, 2):bo_conf(2, 2), bo_conf(1, 3):bo_conf(2, 3)))
3243 cavity = cdft_control%becke_control%cavity%array(lbound(cavity, 1):ubound(cavity, 1), &
3244 bo_conf(1, 2):bo_conf(2, 2), &
3245 bo_conf(1, 3):bo_conf(2, 3))
3246 CALL force_env%para_env%isend(msgin=cavity, &
3247 dest=mixed_cdft%dlb_control%target_list(1, i), &
3253 DEALLOCATE (buffsize)
3256 DEALLOCATE (expected_work, work_size, load_imbalance, work_index, targets)
3260 IF (mixed_cdft%is_special)
THEN
3262 ALLOCATE (mask_send(
SIZE(mixed_cdft%dest_list)), mask_recv(
SIZE(mixed_cdft%source_list)))
3263 ALLOCATE (nsend_proc(
SIZE(mixed_cdft%dest_list)), nrecv(
SIZE(mixed_cdft%source_list)))
3271 ALLOCATE (recvbuffer(
SIZE(mixed_cdft%source_list)), sbuff(
SIZE(mixed_cdft%dest_list)))
3272 ALLOCATE (req_total(my_special_work*
SIZE(mixed_cdft%source_list) + (my_special_work**2)*
SIZE(mixed_cdft%dest_list)))
3273 ALLOCATE (mixed_cdft%dlb_control%recv_work_repl(
SIZE(mixed_cdft%source_list)))
3274 DO i = 1,
SIZE(mixed_cdft%source_list)
3275 NULLIFY (recvbuffer(i)%bv, recvbuffer(i)%iv)
3276 ALLOCATE (recvbuffer(i)%bv(1), recvbuffer(i)%iv(3))
3277 CALL force_env%para_env%irecv(msgout=recvbuffer(i)%bv, &
3278 source=mixed_cdft%source_list(i), &
3279 request=req_total(i), tag=1)
3280 IF (mixed_cdft%is_special)
THEN
3281 CALL force_env%para_env%irecv(msgout=recvbuffer(i)%iv, &
3282 source=mixed_cdft%source_list(i), &
3283 request=req_total(i +
SIZE(mixed_cdft%source_list)), &
3287 DO i = 1, my_special_work
3288 DO j = 1,
SIZE(mixed_cdft%dest_list)
3290 NULLIFY (sbuff(j)%iv, sbuff(j)%bv)
3291 ALLOCATE (sbuff(j)%bv(1))
3292 sbuff(j)%bv = mixed_cdft%dlb_control%send_work
3293 IF (mixed_cdft%is_special)
THEN
3294 ALLOCATE (sbuff(j)%iv(3))
3295 sbuff(j)%iv(1:2) = mixed_cdft%dest_list_bo(1:2, j)
3297 IF (sbuff(j)%iv(1) == should_deallocate) mask_send(j) = .true.
3298 IF (mixed_cdft%dlb_control%send_work)
THEN
3299 sbuff(j)%bv = touched(j)
3300 IF (touched(j))
THEN
3302 DO ispecial = 1,
SIZE(mixed_cdft%dlb_control%target_list, 2)
3303 IF (mixed_cdft%dlb_control%target_list(4 + 2*(j - 1), ispecial) /= uninitialized)
THEN
3307 sbuff(j)%iv(3) = nsend
3308 nsend_proc(j) = nsend
3313 ind = j + (i - 1)*
SIZE(mixed_cdft%dest_list) + my_special_work*
SIZE(mixed_cdft%source_list)
3314 CALL force_env%para_env%isend(msgin=sbuff(j)%bv, &
3315 dest=mixed_cdft%dest_list(j) + (i - 1)*force_env%para_env%num_pe/2, &
3316 request=req_total(ind), tag=1)
3317 IF (mixed_cdft%is_special)
THEN
3318 CALL force_env%para_env%isend(msgin=sbuff(j)%iv, &
3319 dest=mixed_cdft%dest_list(j) + (i - 1)*force_env%para_env%num_pe/2, &
3320 request=req_total(ind + 2*
SIZE(mixed_cdft%dest_list)), tag=2)
3325 DEALLOCATE (req_total)
3326 DO i = 1,
SIZE(mixed_cdft%source_list)
3327 mixed_cdft%dlb_control%recv_work_repl(i) = recvbuffer(i)%bv(1)
3328 IF (mixed_cdft%is_special .AND. mixed_cdft%dlb_control%recv_work_repl(i))
THEN
3329 mixed_cdft%source_list_bo(1:2, i) = recvbuffer(i)%iv(1:2)
3330 nrecv(i) = recvbuffer(i)%iv(3)
3331 IF (recvbuffer(i)%iv(1) == should_deallocate) mask_recv(i) = .true.
3333 DEALLOCATE (recvbuffer(i)%bv)
3334 IF (
ASSOCIATED(recvbuffer(i)%iv))
DEALLOCATE (recvbuffer(i)%iv)
3336 DO j = 1,
SIZE(mixed_cdft%dest_list)
3337 DEALLOCATE (sbuff(j)%bv)
3338 IF (
ASSOCIATED(sbuff(j)%iv))
DEALLOCATE (sbuff(j)%iv)
3340 DEALLOCATE (recvbuffer)
3343 IF (debug_this_module)
THEN
3344 WRITE (dummy, *) mixed_cdft%is_special
3347 IF (.NOT. mixed_cdft%is_special)
THEN
3348 IF (mixed_cdft%dlb_control%send_work)
THEN
3349 ALLOCATE (req_total(count(mixed_cdft%dlb_control%recv_work_repl) + 2))
3350 ALLOCATE (sendbuffer(6))
3351 IF (mixed_cdft%is_pencil)
THEN
3352 sendbuffer = [
SIZE(mixed_cdft%dlb_control%target_list, 2), bo_conf(1, 3), bo_conf(2, 3), &
3353 bo_conf(1, 1), bo_conf(1, 2), bo_conf(2, 2)]
3355 sendbuffer = [
SIZE(mixed_cdft%dlb_control%target_list, 2), bo_conf(1, 3), bo_conf(2, 3), &
3356 bo_conf(1, 2), bo_conf(1, 1), bo_conf(2, 1)]
3358 ELSE IF (any(mixed_cdft%dlb_control%recv_work_repl))
THEN
3359 ALLOCATE (req_total(count(mixed_cdft%dlb_control%recv_work_repl)))
3361 IF (any(mixed_cdft%dlb_control%recv_work_repl))
THEN
3362 ALLOCATE (mixed_cdft%dlb_control%recv_info(2))
3363 NULLIFY (mixed_cdft%dlb_control%recv_info(1)%target_list, mixed_cdft%dlb_control%recv_info(2)%target_list)
3364 ALLOCATE (mixed_cdft%dlb_control%recvbuff(2))
3365 NULLIFY (mixed_cdft%dlb_control%recvbuff(1)%buffs, mixed_cdft%dlb_control%recvbuff(2)%buffs)
3368 IF (mixed_cdft%dlb_control%send_work)
THEN
3369 ind = count(mixed_cdft%dlb_control%recv_work_repl) + 1
3371 CALL force_env%para_env%isend(msgin=sendbuffer, &
3372 dest=mixed_cdft%dest_list(i), &
3373 request=req_total(ind))
3377 IF (any(mixed_cdft%dlb_control%recv_work_repl))
THEN
3380 IF (mixed_cdft%dlb_control%recv_work_repl(i))
THEN
3381 ALLOCATE (mixed_cdft%dlb_control%recv_info(i)%matrix_info(6))
3382 CALL force_env%para_env%irecv(msgout=mixed_cdft%dlb_control%recv_info(i)%matrix_info, &
3383 source=mixed_cdft%source_list(i), &
3384 request=req_total(ind))
3389 IF (
ASSOCIATED(req_total))
THEN
3393 IF (mixed_cdft%dlb_control%send_work)
THEN
3394 ind = count(mixed_cdft%dlb_control%recv_work_repl) + 1
3397 mixed_cdft%dlb_control%target_list(3, :) = mixed_cdft%dlb_control%target_list(3, :) + 3*max_targets
3399 CALL force_env%para_env%isend(msgin=mixed_cdft%dlb_control%target_list, &
3400 dest=mixed_cdft%dest_list(i), &
3401 request=req_total(ind))
3405 IF (any(mixed_cdft%dlb_control%recv_work_repl))
THEN
3408 IF (mixed_cdft%dlb_control%recv_work_repl(i))
THEN
3409 ALLOCATE (mixed_cdft%dlb_control%recv_info(i)% &
3410 target_list(3, mixed_cdft%dlb_control%recv_info(i)%matrix_info(1)))
3411 CALL force_env%para_env%irecv(msgout=mixed_cdft%dlb_control%recv_info(i)%target_list, &
3412 source=mixed_cdft%source_list(i), &
3413 request=req_total(ind))
3418 IF (
ASSOCIATED(req_total))
THEN
3420 DEALLOCATE (req_total)
3422 IF (
ASSOCIATED(sendbuffer))
DEALLOCATE (sendbuffer)
3424 IF (mixed_cdft%dlb_control%send_work)
THEN
3425 ALLOCATE (req_total(count(mixed_cdft%dlb_control%recv_work_repl) + 2*count(touched)))
3426 ELSE IF (any(mixed_cdft%dlb_control%recv_work_repl))
THEN
3427 ALLOCATE (req_total(count(mixed_cdft%dlb_control%recv_work_repl)))
3429 IF (mixed_cdft%dlb_control%send_work)
THEN
3430 ind = count(mixed_cdft%dlb_control%recv_work_repl)
3431 DO j = 1,
SIZE(mixed_cdft%dest_list)
3432 IF (touched(j))
THEN
3433 ALLOCATE (sbuff(j)%iv(4 + 3*nsend_proc(j)))
3434 sbuff(j)%iv(1:4) = [bo_conf(1, 2), bo_conf(2, 2), bo_conf(1, 3), bo_conf(2, 3)]
3436 DO i = 1,
SIZE(mixed_cdft%dlb_control%target_list, 2)
3437 IF (mixed_cdft%dlb_control%target_list(4 + 2*(j - 1), i) /= uninitialized)
THEN
3438 sbuff(j)%iv(offset:offset + 2) = [mixed_cdft%dlb_control%target_list(1, i), &
3439 mixed_cdft%dlb_control%target_list(4 + 2*(j - 1), i), &
3440 mixed_cdft%dlb_control%target_list(4 + 2*j - 1, i)]
3444 DO ispecial = 1, my_special_work
3445 CALL force_env%para_env%isend(msgin=sbuff(j)%iv, &
3446 dest=mixed_cdft%dest_list(j) + (ispecial - 1)*force_env%para_env%num_pe/2, &
3447 request=req_total(ind + ispecial))
3449 ind = ind + my_special_work
3453 IF (any(mixed_cdft%dlb_control%recv_work_repl))
THEN
3454 ALLOCATE (mixed_cdft%dlb_control%recv_info(
SIZE(mixed_cdft%source_list)))
3455 ALLOCATE (mixed_cdft%dlb_control%recvbuff(
SIZE(mixed_cdft%source_list)))
3457 DO j = 1,
SIZE(mixed_cdft%source_list)
3458 NULLIFY (mixed_cdft%dlb_control%recv_info(j)%target_list, &
3459 mixed_cdft%dlb_control%recvbuff(j)%buffs)
3460 IF (mixed_cdft%dlb_control%recv_work_repl(j))
THEN
3461 ALLOCATE (mixed_cdft%dlb_control%recv_info(j)%matrix_info(4 + 3*nrecv(j)))
3462 CALL force_env%para_env%irecv(mixed_cdft%dlb_control%recv_info(j)%matrix_info, &
3463 source=mixed_cdft%source_list(j), &
3464 request=req_total(ind))
3469 IF (
ASSOCIATED(req_total))
THEN
3471 DEALLOCATE (req_total)
3473 IF (any(mask_send))
THEN
3474 ALLOCATE (tmp(
SIZE(mixed_cdft%dest_list) - count(mask_send)), &
3475 tmp_bo(2,
SIZE(mixed_cdft%dest_list) - count(mask_send)))
3477 DO j = 1,
SIZE(mixed_cdft%dest_list)
3478 IF (.NOT. mask_send(j))
THEN
3479 tmp(i) = mixed_cdft%dest_list(j)
3480 tmp_bo(1:2, i) = mixed_cdft%dest_list_bo(1:2, j)
3484 DEALLOCATE (mixed_cdft%dest_list, mixed_cdft%dest_list_bo)
3485 ALLOCATE (mixed_cdft%dest_list(
SIZE(tmp)), mixed_cdft%dest_list_bo(2,
SIZE(tmp)))
3486 mixed_cdft%dest_list = tmp
3487 mixed_cdft%dest_list_bo = tmp_bo
3488 DEALLOCATE (tmp, tmp_bo)
3490 IF (any(mask_recv))
THEN
3491 ALLOCATE (tmp(
SIZE(mixed_cdft%source_list) - count(mask_recv)), &
3492 tmp_bo(4,
SIZE(mixed_cdft%source_list) - count(mask_recv)))
3494 DO j = 1,
SIZE(mixed_cdft%source_list)
3495 IF (.NOT. mask_recv(j))
THEN
3496 tmp(i) = mixed_cdft%source_list(j)
3497 tmp_bo(1:4, i) = mixed_cdft%source_list_bo(1:4, j)
3501 DEALLOCATE (mixed_cdft%source_list, mixed_cdft%source_list_bo)
3502 ALLOCATE (mixed_cdft%source_list(
SIZE(tmp)), mixed_cdft%source_list_bo(4,
SIZE(tmp)))
3503 mixed_cdft%source_list = tmp
3504 mixed_cdft%source_list_bo = tmp_bo
3505 DEALLOCATE (tmp, tmp_bo)
3507 DEALLOCATE (mask_recv, mask_send)
3508 DEALLOCATE (nsend_proc, nrecv)
3509 IF (mixed_cdft%dlb_control%send_work)
THEN
3510 DO j = 1,
SIZE(mixed_cdft%dest_list)
3511 IF (touched(j))
DEALLOCATE (sbuff(j)%iv)
3513 IF (
ASSOCIATED(touched))
DEALLOCATE (touched)
3518 "MIXED%MIXED_CDFT%PRINT%PROGRAM_RUN_INFO")
3519 CALL timestop(handle)
3521 END SUBROUTINE mixed_becke_constraint_dlb
3540 SUBROUTINE mixed_becke_constraint_low(force_env, mixed_cdft, in_memory, &
3541 is_constraint, store_vectors, R12, position_vecs, &
3542 pair_dist_vecs, coefficients, catom)
3545 LOGICAL,
INTENT(IN) :: in_memory
3546 LOGICAL,
ALLOCATABLE,
DIMENSION(:),
INTENT(INOUT) :: is_constraint
3547 LOGICAL,
INTENT(IN) :: store_vectors
3548 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :), &
3549 INTENT(INOUT) :: r12, position_vecs
3550 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :, :), &
3551 INTENT(INOUT) :: pair_dist_vecs
3552 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:), &
3553 INTENT(INOUT) :: coefficients
3554 INTEGER,
ALLOCATABLE,
DIMENSION(:),
INTENT(INOUT) :: catom
3556 CHARACTER(len=*),
PARAMETER :: routinen =
'mixed_becke_constraint_low'
3557 REAL(kind=
dp),
PARAMETER :: eps_sum_cell_f_all = 1.0e-06_dp
3559 INTEGER :: handle, i, iatom, icomm, iforce_eval, index, iounit, ip, ispecial, iwork, j, &
3560 jatom, jcomm, k, my_special_work, my_work, natom, nbuffs, nforce_eval, np(3), &
3561 nsent_total, nskipped, nwork, offset, offset_repl
3562 INTEGER,
DIMENSION(:),
POINTER :: work, work_dlb
3563 INTEGER,
DIMENSION(:, :),
POINTER :: nsent
3564 LOGICAL :: completed_recv, should_communicate
3565 LOGICAL,
ALLOCATABLE,
DIMENSION(:) :: skip_me
3566 LOGICAL,
ALLOCATABLE,
DIMENSION(:, :) :: completed
3567 REAL(kind=
dp) :: dist1, dist2, dmyexp, my1, my1_homo, &
3568 myexp, sum_cell_f_all, &
3569 sum_cell_f_constr, th, tmp_const
3570 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: cell_functions, distances, ds_dr_i, &
3572 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: d_sum_const_dr, d_sum_pm_dr, &
3573 distance_vecs, dp_i_dri
3574 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :, :) :: dp_i_drj
3575 REAL(kind=
dp),
DIMENSION(3) :: cell_v, dist_vec, dmy_dr_i, dmy_dr_j, &
3576 dr, dr1_r2, dr_i_dr, dr_ij_dr, &
3577 dr_j_dr, grid_p, r, r1, shift
3578 REAL(kind=
dp),
DIMENSION(:),
POINTER :: cutoffs
3579 REAL(kind=
dp),
DIMENSION(:, :, :),
POINTER :: cavity, weight
3580 REAL(kind=
dp),
DIMENSION(:, :, :, :),
POINTER :: gradients
3594 NULLIFY (work, req_recv, req_send, work_dlb, nsent, cutoffs, cavity, &
3595 weight, gradients, cell, subsys_mix, force_env_qs, &
3596 particle_set, particles, auxbas_pw_pool, force_env_section, &
3597 print_section, cdft_control)
3598 CALL timeset(routinen, handle)
3599 nforce_eval =
SIZE(force_env%sub_force_env)
3600 CALL force_env_get(force_env=force_env, force_env_section=force_env_section)
3603 IF (.NOT. force_env%mixed_env%do_mixed_qmmm_cdft)
THEN
3605 subsys=subsys_mix, &
3608 particles=particles, &
3609 particle_set=particle_set)
3611 DO iforce_eval = 1, nforce_eval
3612 IF (.NOT.
ASSOCIATED(force_env%sub_force_env(iforce_eval)%force_env)) cycle
3613 force_env_qs => force_env%sub_force_env(iforce_eval)%force_env
3615 CALL get_qs_env(force_env_qs%qmmm_env%qs_env, &
3616 cp_subsys=subsys_mix, &
3619 particles=particles, &
3620 particle_set=particle_set)
3622 natom =
SIZE(particles%els)
3623 cdft_control => mixed_cdft%cdft_control
3624 CALL pw_env_get(pw_env=mixed_cdft%pw_env, auxbas_pw_pool=auxbas_pw_pool)
3625 np = auxbas_pw_pool%pw_grid%npts
3626 dr = auxbas_pw_pool%pw_grid%dr
3627 shift = -real(
modulo(np, 2),
dp)*dr/2.0_dp
3628 ALLOCATE (cell_functions(natom), skip_me(natom))
3629 IF (store_vectors)
THEN
3630 ALLOCATE (distances(natom))
3631 ALLOCATE (distance_vecs(3, natom))
3634 ALLOCATE (ds_dr_j(3))
3635 ALLOCATE (ds_dr_i(3))
3636 ALLOCATE (d_sum_pm_dr(3, natom))
3637 ALLOCATE (d_sum_const_dr(3, natom))
3638 ALLOCATE (dp_i_drj(3, natom, natom))
3639 ALLOCATE (dp_i_dri(3, natom))
3642 IF (mixed_cdft%dlb)
THEN
3643 ALLOCATE (work(force_env%para_env%num_pe), work_dlb(force_env%para_env%num_pe))
3650 IF (mixed_cdft%dlb)
THEN
3651 IF (mixed_cdft%dlb_control%recv_work)
THEN
3653 IF (.NOT. mixed_cdft%is_special)
THEN
3654 ALLOCATE (req_send(2, 3))
3656 ALLOCATE (req_send(2, 3*
SIZE(mixed_cdft%dlb_control%sendbuff)))
3659 IF (any(mixed_cdft%dlb_control%recv_work_repl))
THEN
3660 IF (.NOT. mixed_cdft%is_special)
THEN
3662 IF (mixed_cdft%dlb_control%recv_work_repl(1) .AND. mixed_cdft%dlb_control%recv_work_repl(2))
THEN
3663 ALLOCATE (req_recv(3*(
SIZE(mixed_cdft%dlb_control%recv_info(1)%target_list, 2) + &
3664 SIZE(mixed_cdft%dlb_control%recv_info(2)%target_list, 2))))
3665 offset_repl = 3*
SIZE(mixed_cdft%dlb_control%recv_info(1)%target_list, 2)
3666 ELSE IF (mixed_cdft%dlb_control%recv_work_repl(1))
THEN
3667 ALLOCATE (req_recv(3*(
SIZE(mixed_cdft%dlb_control%recv_info(1)%target_list, 2))))
3669 ALLOCATE (req_recv(3*(
SIZE(mixed_cdft%dlb_control%recv_info(2)%target_list, 2))))
3674 DO j = 1,
SIZE(mixed_cdft%dlb_control%recv_work_repl)
3675 IF (mixed_cdft%dlb_control%recv_work_repl(j))
THEN
3676 nbuffs = nbuffs + (
SIZE(mixed_cdft%dlb_control%recv_info(j)%matrix_info) - 4)/3
3679 ALLOCATE (req_recv(3*nbuffs))
3681 DO j = 1,
SIZE(mixed_cdft%dlb_control%recv_work_repl)
3682 IF (mixed_cdft%dlb_control%recv_work_repl(j))
THEN
3683 IF (.NOT. mixed_cdft%is_special)
THEN
3686 ALLOCATE (mixed_cdft%dlb_control%recvbuff(j)%buffs(
SIZE(mixed_cdft%dlb_control%recv_info(j)%target_list, 2)))
3687 DO i = 1,
SIZE(mixed_cdft%dlb_control%recv_info(j)%target_list, 2)
3688 IF (mixed_cdft%is_pencil)
THEN
3689 ALLOCATE (mixed_cdft%dlb_control%recvbuff(j)%buffs(i)% &
3690 weight(mixed_cdft%dlb_control%recv_info(j)%matrix_info(4) + offset: &
3691 mixed_cdft%dlb_control%recv_info(j)%matrix_info(4) + offset + &
3692 (mixed_cdft%dlb_control%recv_info(j)%target_list(2, i) - 1), &
3693 mixed_cdft%dlb_control%recv_info(j)%matrix_info(5): &
3694 mixed_cdft%dlb_control%recv_info(j)%matrix_info(6), &
3695 mixed_cdft%dlb_control%recv_info(j)%matrix_info(2): &
3696 mixed_cdft%dlb_control%recv_info(j)%matrix_info(3)))
3697 ALLOCATE (mixed_cdft%dlb_control%recvbuff(j)%buffs(i)% &
3698 cavity(mixed_cdft%dlb_control%recv_info(j)%matrix_info(4) + offset: &
3699 mixed_cdft%dlb_control%recv_info(j)%matrix_info(4) + offset + &
3700 (mixed_cdft%dlb_control%recv_info(j)%target_list(2, i) - 1), &
3701 mixed_cdft%dlb_control%recv_info(j)%matrix_info(5): &
3702 mixed_cdft%dlb_control%recv_info(j)%matrix_info(6), &
3703 mixed_cdft%dlb_control%recv_info(j)%matrix_info(2): &
3704 mixed_cdft%dlb_control%recv_info(j)%matrix_info(3)))
3705 ALLOCATE (mixed_cdft%dlb_control%recvbuff(j)%buffs(i)% &
3706 gradients(3*natom, &
3707 mixed_cdft%dlb_control%recv_info(j)%matrix_info(4) + offset: &
3708 mixed_cdft%dlb_control%recv_info(j)%matrix_info(4) + offset + &
3709 (mixed_cdft%dlb_control%recv_info(j)%target_list(2, i) - 1), &
3710 mixed_cdft%dlb_control%recv_info(j)%matrix_info(5): &
3711 mixed_cdft%dlb_control%recv_info(j)%matrix_info(6), &
3712 mixed_cdft%dlb_control%recv_info(j)%matrix_info(2): &
3713 mixed_cdft%dlb_control%recv_info(j)%matrix_info(3)))
3715 ALLOCATE (mixed_cdft%dlb_control%recvbuff(j)%buffs(i)% &
3716 weight(mixed_cdft%dlb_control%recv_info(j)%matrix_info(5): &
3717 mixed_cdft%dlb_control%recv_info(j)%matrix_info(6), &
3718 mixed_cdft%dlb_control%recv_info(j)%matrix_info(4) + offset: &
3719 mixed_cdft%dlb_control%recv_info(j)%matrix_info(4) + offset + &
3720 (mixed_cdft%dlb_control%recv_info(j)%target_list(2, i) - 1), &
3721 mixed_cdft%dlb_control%recv_info(j)%matrix_info(2): &
3722 mixed_cdft%dlb_control%recv_info(j)%matrix_info(3)))
3723 ALLOCATE (mixed_cdft%dlb_control%recvbuff(j)%buffs(i)% &
3724 cavity(mixed_cdft%dlb_control%recv_info(j)%matrix_info(5): &
3725 mixed_cdft%dlb_control%recv_info(j)%matrix_info(6), &
3726 mixed_cdft%dlb_control%recv_info(j)%matrix_info(4) + offset: &
3727 mixed_cdft%dlb_control%recv_info(j)%matrix_info(4) + offset + &
3728 (mixed_cdft%dlb_control%recv_info(j)%target_list(2, i) - 1), &
3729 mixed_cdft%dlb_control%recv_info(j)%matrix_info(2): &
3730 mixed_cdft%dlb_control%recv_info(j)%matrix_info(3)))
3731 ALLOCATE (mixed_cdft%dlb_control%recvbuff(j)%buffs(i)% &
3732 gradients(3*natom, &
3733 mixed_cdft%dlb_control%recv_info(j)%matrix_info(5): &
3734 mixed_cdft%dlb_control%recv_info(j)%matrix_info(6), &
3735 mixed_cdft%dlb_control%recv_info(j)%matrix_info(4) + offset: &
3736 mixed_cdft%dlb_control%recv_info(j)%matrix_info(4) + offset + &
3737 (mixed_cdft%dlb_control%recv_info(j)%target_list(2, i) - 1), &
3738 mixed_cdft%dlb_control%recv_info(j)%matrix_info(2): &
3739 mixed_cdft%dlb_control%recv_info(j)%matrix_info(3)))
3742 CALL force_env%para_env%irecv(msgout=mixed_cdft%dlb_control%recvbuff(j)%buffs(i)%cavity, &
3743 source=mixed_cdft%dlb_control%recv_info(j)%target_list(1, i), &
3744 request=req_recv(3*(i - 1) + (j - 1)*offset_repl + 1), &
3745 tag=mixed_cdft%dlb_control%recv_info(j)%target_list(3, i))
3746 CALL force_env%para_env%irecv(msgout=mixed_cdft%dlb_control%recvbuff(j)%buffs(i)%weight, &
3747 source=mixed_cdft%dlb_control%recv_info(j)%target_list(1, i), &
3748 request=req_recv(3*(i - 1) + (j - 1)*offset_repl + 2), &
3749 tag=mixed_cdft%dlb_control%recv_info(j)%target_list(3, i) + 1)
3750 CALL force_env%para_env%irecv(msgout=mixed_cdft%dlb_control%recvbuff(j)%buffs(i)%gradients, &
3751 source=mixed_cdft%dlb_control%recv_info(j)%target_list(1, i), &
3752 request=req_recv(3*(i - 1) + (j - 1)*offset_repl + 3), &
3753 tag=mixed_cdft%dlb_control%recv_info(j)%target_list(3, i) + 2)
3754 offset = offset + mixed_cdft%dlb_control%recv_info(j)%target_list(2, i)
3756 DEALLOCATE (mixed_cdft%dlb_control%recv_info(j)%matrix_info)
3758 ALLOCATE (mixed_cdft%dlb_control%recvbuff(j)% &
3759 buffs((
SIZE(mixed_cdft%dlb_control%recv_info(j)%matrix_info) - 4)/3))
3761 DO i = 1,
SIZE(mixed_cdft%dlb_control%recvbuff(j)%buffs)
3762 ALLOCATE (mixed_cdft%dlb_control%recvbuff(j)%buffs(i)% &
3763 weight(mixed_cdft%dlb_control%recv_info(j)%matrix_info(index): &
3764 mixed_cdft%dlb_control%recv_info(j)%matrix_info(index + 1), &
3765 mixed_cdft%dlb_control%recv_info(j)%matrix_info(1): &
3766 mixed_cdft%dlb_control%recv_info(j)%matrix_info(2), &
3767 mixed_cdft%dlb_control%recv_info(j)%matrix_info(3): &
3768 mixed_cdft%dlb_control%recv_info(j)%matrix_info(4)))
3769 ALLOCATE (mixed_cdft%dlb_control%recvbuff(j)%buffs(i)% &
3770 cavity(mixed_cdft%dlb_control%recv_info(j)%matrix_info(index): &
3771 mixed_cdft%dlb_control%recv_info(j)%matrix_info(index + 1), &
3772 mixed_cdft%dlb_control%recv_info(j)%matrix_info(1): &
3773 mixed_cdft%dlb_control%recv_info(j)%matrix_info(2), &
3774 mixed_cdft%dlb_control%recv_info(j)%matrix_info(3): &
3775 mixed_cdft%dlb_control%recv_info(j)%matrix_info(4)))
3776 ALLOCATE (mixed_cdft%dlb_control%recvbuff(j)%buffs(i)% &
3777 gradients(3*natom, mixed_cdft%dlb_control%recv_info(j)%matrix_info(index): &
3778 mixed_cdft%dlb_control%recv_info(j)%matrix_info(index + 1), &
3779 mixed_cdft%dlb_control%recv_info(j)%matrix_info(1): &
3780 mixed_cdft%dlb_control%recv_info(j)%matrix_info(2), &
3781 mixed_cdft%dlb_control%recv_info(j)%matrix_info(3): &
3782 mixed_cdft%dlb_control%recv_info(j)%matrix_info(4)))
3783 CALL force_env%para_env%irecv(msgout=mixed_cdft%dlb_control%recvbuff(j)%buffs(i)%cavity, &
3784 source=mixed_cdft%dlb_control%recv_info(j)%matrix_info(index - 1), &
3785 request=req_recv(offset_repl), tag=1)
3786 CALL force_env%para_env%irecv(msgout=mixed_cdft%dlb_control%recvbuff(j)%buffs(i)%weight, &
3787 source=mixed_cdft%dlb_control%recv_info(j)%matrix_info(index - 1), &
3788 request=req_recv(offset_repl + 1), tag=2)
3789 CALL force_env%para_env%irecv(msgout=mixed_cdft%dlb_control%recvbuff(j)%buffs(i)%gradients, &
3790 source=mixed_cdft%dlb_control%recv_info(j)%matrix_info(index - 1), &
3791 request=req_recv(offset_repl + 2), tag=3)
3793 offset_repl = offset_repl + 3
3795 DEALLOCATE (mixed_cdft%dlb_control%recv_info(j)%matrix_info)
3801 cutoffs => cdft_control%becke_control%cutoffs
3802 should_communicate = .false.
3804 cell_v(i) = cell%hmat(i, i)
3806 DO iwork = my_work, 1, -1
3807 IF (iwork == 2)
THEN
3808 IF (.NOT. mixed_cdft%is_special)
THEN
3809 cavity => mixed_cdft%dlb_control%cavity
3810 weight => mixed_cdft%dlb_control%weight
3811 gradients => mixed_cdft%dlb_control%gradients
3812 ALLOCATE (completed(2, 3), nsent(2, 3))
3814 my_special_work =
SIZE(mixed_cdft%dlb_control%sendbuff)
3815 ALLOCATE (completed(2, 3*my_special_work), nsent(2, 3*my_special_work))
3820 IF (.NOT. mixed_cdft%is_special)
THEN
3821 weight => mixed_cdft%weight
3822 cavity => mixed_cdft%cavity
3823 gradients => cdft_control%group(1)%gradients
3825 my_special_work =
SIZE(mixed_cdft%dest_list)
3828 DO ispecial = 1, my_special_work
3830 IF (mixed_cdft%is_special)
THEN
3831 IF (iwork == 1)
THEN
3832 weight => mixed_cdft%sendbuff(ispecial)%weight
3833 cavity => mixed_cdft%sendbuff(ispecial)%cavity
3834 gradients => mixed_cdft%sendbuff(ispecial)%gradients
3836 weight => mixed_cdft%dlb_control%sendbuff(ispecial)%weight
3837 cavity => mixed_cdft%dlb_control%sendbuff(ispecial)%cavity
3838 gradients => mixed_cdft%dlb_control%sendbuff(ispecial)%gradients
3841 DO k = lbound(weight, 1), ubound(weight, 1)
3842 IF (mixed_cdft%dlb .AND. mixed_cdft%is_pencil .AND. .NOT. mixed_cdft%is_special)
THEN
3843 IF (mixed_cdft%dlb_control%send_work)
THEN
3844 IF (k >= mixed_cdft%dlb_control%distributed(1) .AND. &
3845 k <= mixed_cdft%dlb_control%distributed(2))
THEN
3850 DO j = lbound(weight, 2), ubound(weight, 2)
3851 IF (mixed_cdft%dlb .AND. .NOT. mixed_cdft%is_pencil .AND. .NOT. mixed_cdft%is_special)
THEN
3852 IF (mixed_cdft%dlb_control%send_work)
THEN
3853 IF (j >= mixed_cdft%dlb_control%distributed(1) .AND. &
3854 j <= mixed_cdft%dlb_control%distributed(2))
THEN
3860 IF (should_communicate)
THEN
3861 DO icomm = 1,
SIZE(nsent, 2)
3862 DO jcomm = 1,
SIZE(nsent, 1)
3863 IF (nsent(jcomm, icomm) == 1) cycle
3864 completed(jcomm, icomm) = req_send(jcomm, icomm)%test()
3865 IF (completed(jcomm, icomm))
THEN
3866 nsent(jcomm, icomm) = nsent(jcomm, icomm) + 1
3867 nsent_total = nsent_total + 1
3868 IF (nsent_total ==
SIZE(nsent, 1)*
SIZE(nsent, 2)) should_communicate = .false.
3870 IF (all(completed(:, icomm)))
THEN
3871 IF (
modulo(icomm, 3) == 1)
THEN
3872 IF (.NOT. mixed_cdft%is_special)
THEN
3873 DEALLOCATE (mixed_cdft%dlb_control%cavity)
3875 DEALLOCATE (mixed_cdft%dlb_control%sendbuff((icomm - 1)/3 + 1)%cavity)
3877 ELSE IF (
modulo(icomm, 3) == 2)
THEN
3878 IF (.NOT. mixed_cdft%is_special)
THEN
3879 DEALLOCATE (mixed_cdft%dlb_control%weight)
3881 DEALLOCATE (mixed_cdft%dlb_control%sendbuff((icomm - 1)/3 + 1)%weight)
3884 IF (.NOT. mixed_cdft%is_special)
THEN
3885 DEALLOCATE (mixed_cdft%dlb_control%gradients)
3887 DEALLOCATE (mixed_cdft%dlb_control%sendbuff((icomm - 1)/3 + 1)%gradients)
3895 IF (
ASSOCIATED(req_recv))
THEN
3899 DO i = lbound(weight, 3), ubound(weight, 3)
3900 IF (cdft_control%becke_control%cavity_confine)
THEN
3901 IF (cavity(k, j, i) < cdft_control%becke_control%eps_cavity) cycle
3903 grid_p(1) = k*dr(1) + shift(1)
3904 grid_p(2) = j*dr(2) + shift(2)
3905 grid_p(3) = i*dr(3) + shift(3)
3907 cell_functions = 1.0_dp
3909 IF (store_vectors) distances = 0.0_dp
3911 d_sum_pm_dr = 0.0_dp
3912 d_sum_const_dr = 0.0_dp
3916 IF (skip_me(iatom))
THEN
3917 cell_functions(iatom) = 0.0_dp
3918 IF (cdft_control%becke_control%should_skip)
THEN
3919 IF (is_constraint(iatom)) nskipped = nskipped + 1
3920 IF (nskipped == cdft_control%natoms)
THEN
3922 IF (cdft_control%becke_control%cavity_confine)
THEN
3923 cavity(k, j, i) = 0.0_dp
3931 IF (store_vectors)
THEN
3932 IF (distances(iatom) == 0.0_dp)
THEN
3933 r = position_vecs(:, iatom)
3934 dist_vec = (r - grid_p) - anint((r - grid_p)/cell_v)*cell_v
3935 dist1 = norm2(dist_vec)
3936 distance_vecs(:, iatom) = dist_vec
3937 distances(iatom) = dist1
3939 dist_vec = distance_vecs(:, iatom)
3940 dist1 = distances(iatom)
3943 r = particle_set(iatom)%r
3945 r(ip) =
modulo(r(ip), cell%hmat(ip, ip)) - cell%hmat(ip, ip)/2._dp
3947 dist_vec = (r - grid_p) - anint((r - grid_p)/cell_v)*cell_v
3948 dist1 = norm2(dist_vec)
3950 IF (dist1 <= cutoffs(iatom))
THEN
3952 IF (dist1 <= th) dist1 = th
3953 dr_i_dr(:) = dist_vec(:)/dist1
3956 IF (jatom /= iatom)
THEN
3957 IF (jatom < iatom)
THEN
3958 IF (.NOT. skip_me(jatom)) cycle
3960 IF (store_vectors)
THEN
3961 IF (distances(jatom) == 0.0_dp)
THEN
3962 r1 = position_vecs(:, jatom)
3963 dist_vec = (r1 - grid_p) - anint((r1 - grid_p)/cell_v)*cell_v
3964 dist2 = norm2(dist_vec)
3965 distance_vecs(:, jatom) = dist_vec
3966 distances(jatom) = dist2
3968 dist_vec = distance_vecs(:, jatom)
3969 dist2 = distances(jatom)
3972 r1 = particle_set(jatom)%r
3974 r1(ip) =
modulo(r1(ip), cell%hmat(ip, ip)) - cell%hmat(ip, ip)/2._dp
3976 dist_vec = (r1 - grid_p) - anint((r1 - grid_p)/cell_v)*cell_v
3977 dist2 = norm2(dist_vec)
3980 IF (store_vectors)
THEN
3981 dr1_r2 = pair_dist_vecs(:, iatom, jatom)
3983 dr1_r2 = (r - r1) - anint((r - r1)/cell_v)*cell_v
3985 IF (dist2 <= th) dist2 = th
3986 tmp_const = (r12(iatom, jatom)**3)
3987 dr_ij_dr(:) = dr1_r2(:)/tmp_const
3989 dr_j_dr = dist_vec(:)/dist2
3990 dmy_dr_j(:) = -(dr_j_dr(:)/r12(iatom, jatom) - (dist1 - dist2)*dr_ij_dr(:))
3992 dmy_dr_i(:) = dr_i_dr(:)/r12(iatom, jatom) - (dist1 - dist2)*dr_ij_dr(:)
3994 my1 = (dist1 - dist2)/r12(iatom, jatom)
3995 IF (cdft_control%becke_control%adjust)
THEN
3998 cdft_control%becke_control%aij(iatom, jatom)*(1.0_dp - my1**2)
4000 myexp = 1.5_dp*my1 - 0.5_dp*my1**3
4002 dmyexp = 1.5_dp - 1.5_dp*my1**2
4003 tmp_const = (1.5_dp**2)*dmyexp*(1 - myexp**2)* &
4004 (1.0_dp - ((1.5_dp*myexp - 0.5_dp*(myexp**3))**2))
4006 ds_dr_i(:) = -0.5_dp*tmp_const*dmy_dr_i(:)
4007 ds_dr_j(:) = -0.5_dp*tmp_const*dmy_dr_j(:)
4008 IF (cdft_control%becke_control%adjust)
THEN
4009 tmp_const = 1.0_dp - 2.0_dp*my1_homo*cdft_control%becke_control%aij(iatom, jatom)
4010 ds_dr_i(:) = ds_dr_i(:)*tmp_const
4011 ds_dr_j(:) = ds_dr_j(:)*tmp_const
4014 myexp = 1.5_dp*myexp - 0.5_dp*myexp**3
4015 myexp = 1.5_dp*myexp - 0.5_dp*myexp**3
4016 tmp_const = 0.5_dp*(1.0_dp - myexp)
4017 cell_functions(iatom) = cell_functions(iatom)*tmp_const
4019 IF (abs(tmp_const) <= th) tmp_const = tmp_const + th
4020 dp_i_dri(:, iatom) = dp_i_dri(:, iatom) + ds_dr_i(:)/tmp_const
4021 dp_i_drj(:, iatom, jatom) = ds_dr_j(:)/tmp_const
4024 IF (dist2 <= cutoffs(jatom))
THEN
4025 tmp_const = 0.5_dp*(1.0_dp + myexp)
4026 cell_functions(jatom) = cell_functions(jatom)*tmp_const
4028 IF (abs(tmp_const) <= th) tmp_const = tmp_const + th
4029 dp_i_drj(:, jatom, iatom) = -ds_dr_i(:)/tmp_const
4030 dp_i_dri(:, jatom) = dp_i_dri(:, jatom) - ds_dr_j(:)/tmp_const
4033 skip_me(jatom) = .true.
4038 dp_i_dri(:, iatom) = cell_functions(iatom)*dp_i_dri(:, iatom)
4039 d_sum_pm_dr(:, iatom) = d_sum_pm_dr(:, iatom) + dp_i_dri(:, iatom)
4040 IF (is_constraint(iatom))
THEN
4041 d_sum_const_dr(:, iatom) = d_sum_const_dr(:, iatom) + dp_i_dri(:, iatom)* &
4045 IF (jatom /= iatom)
THEN
4046 IF (jatom < iatom)
THEN
4047 IF (.NOT. skip_me(jatom))
THEN
4048 dp_i_drj(:, iatom, jatom) = cell_functions(iatom)*dp_i_drj(:, iatom, jatom)
4049 d_sum_pm_dr(:, jatom) = d_sum_pm_dr(:, jatom) + dp_i_drj(:, iatom, jatom)
4050 IF (is_constraint(iatom))
THEN
4051 d_sum_const_dr(:, jatom) = d_sum_const_dr(:, jatom) + &
4052 dp_i_drj(:, iatom, jatom)* &
4058 dp_i_drj(:, iatom, jatom) = cell_functions(iatom)*dp_i_drj(:, iatom, jatom)
4059 d_sum_pm_dr(:, jatom) = d_sum_pm_dr(:, jatom) + dp_i_drj(:, iatom, jatom)
4060 IF (is_constraint(iatom))
THEN
4061 d_sum_const_dr(:, jatom) = d_sum_const_dr(:, jatom) + dp_i_drj(:, iatom, jatom)* &
4068 cell_functions(iatom) = 0.0_dp
4069 skip_me(iatom) = .true.
4070 IF (cdft_control%becke_control%should_skip)
THEN
4071 IF (is_constraint(iatom)) nskipped = nskipped + 1
4072 IF (nskipped == cdft_control%natoms)
THEN
4074 IF (cdft_control%becke_control%cavity_confine)
THEN
4075 cavity(k, j, i) = 0.0_dp
4083 IF (nskipped == cdft_control%natoms) cycle
4084 sum_cell_f_constr = 0.0_dp
4085 DO ip = 1, cdft_control%natoms
4086 sum_cell_f_constr = sum_cell_f_constr + cell_functions(catom(ip))* &
4087 cdft_control%group(1)%coeff(ip)
4089 sum_cell_f_all = 0.0_dp
4092 sum_cell_f_all = sum_cell_f_all + cell_functions(ip)
4096 IF (abs(sum_cell_f_all) > 0.0_dp)
THEN
4097 gradients(3*(iatom - 1) + 1:3*(iatom - 1) + 3, k, j, i) = &
4098 d_sum_const_dr(:, iatom)/sum_cell_f_all - sum_cell_f_constr* &
4099 d_sum_pm_dr(:, iatom)/(sum_cell_f_all**2)
4103 IF (abs(sum_cell_f_all) > eps_sum_cell_f_all)
THEN
4104 weight(k, j, i) = sum_cell_f_constr/sum_cell_f_all
4110 IF (iwork == 2)
THEN
4111 IF (.NOT. mixed_cdft%is_special)
THEN
4112 DO i = 1,
SIZE(req_send, 1)
4113 CALL force_env%para_env%isend(msgin=mixed_cdft%dlb_control%cavity, &
4114 dest=mixed_cdft%dlb_control%my_dest_repl(i), &
4115 request=req_send(i, 1), &
4116 tag=mixed_cdft%dlb_control%dest_tags_repl(i))
4117 CALL force_env%para_env%isend(msgin=mixed_cdft%dlb_control%weight, &
4118 dest=mixed_cdft%dlb_control%my_dest_repl(i), &
4119 request=req_send(i, 2), &
4120 tag=mixed_cdft%dlb_control%dest_tags_repl(i) + 1)
4121 CALL force_env%para_env%isend(msgin=mixed_cdft%dlb_control%gradients, &
4122 dest=mixed_cdft%dlb_control%my_dest_repl(i), &
4123 request=req_send(i, 3), &
4124 tag=mixed_cdft%dlb_control%dest_tags_repl(i) + 2)
4126 should_communicate = .true.
4129 DO i = 1,
SIZE(req_send, 1)
4130 CALL force_env%para_env%isend(msgin=mixed_cdft%dlb_control%sendbuff(ispecial)%cavity, &
4131 dest=mixed_cdft%dlb_control%sendbuff(ispecial)%rank(i), &
4132 request=req_send(i, 3*(ispecial - 1) + 1), tag=1)
4133 CALL force_env%para_env%isend(msgin=mixed_cdft%dlb_control%sendbuff(ispecial)%weight, &
4134 dest=mixed_cdft%dlb_control%sendbuff(ispecial)%rank(i), &
4135 request=req_send(i, 3*(ispecial - 1) + 2), tag=2)
4136 CALL force_env%para_env%isend(msgin=mixed_cdft%dlb_control%sendbuff(ispecial)%gradients, &
4137 dest=mixed_cdft%dlb_control%sendbuff(ispecial)%rank(i), &
4138 request=req_send(i, 3*(ispecial - 1) + 3), tag=3)
4140 IF (ispecial == my_special_work)
THEN
4141 should_communicate = .true.
4145 work(mixed_cdft%dlb_control%my_source + 1) = work(mixed_cdft%dlb_control%my_source + 1) + nwork
4146 work_dlb(force_env%para_env%mepos + 1) = work_dlb(force_env%para_env%mepos + 1) + nwork
4148 IF (mixed_cdft%dlb) work(force_env%para_env%mepos + 1) = work(force_env%para_env%mepos + 1) + nwork
4149 IF (mixed_cdft%dlb) work_dlb(force_env%para_env%mepos + 1) = work_dlb(force_env%para_env%mepos + 1) + nwork
4154 IF (mixed_cdft%dlb)
THEN
4155 IF (mixed_cdft%dlb_control%recv_work .AND. &
4156 any(mixed_cdft%dlb_control%recv_work_repl))
THEN
4157 ALLOCATE (req_total(
SIZE(req_recv) +
SIZE(req_send, 1)*
SIZE(req_send, 2)))
4158 index =
SIZE(req_recv)
4159 req_total(1:index) = req_recv
4160 DO i = 1,
SIZE(req_send, 2)
4161 DO j = 1,
SIZE(req_send, 1)
4163 req_total(index) = req_send(j, i)
4167 DEALLOCATE (req_total)
4168 IF (
ASSOCIATED(mixed_cdft%dlb_control%cavity))
THEN
4169 DEALLOCATE (mixed_cdft%dlb_control%cavity)
4171 IF (
ASSOCIATED(mixed_cdft%dlb_control%weight))
THEN
4172 DEALLOCATE (mixed_cdft%dlb_control%weight)
4174 IF (
ASSOCIATED(mixed_cdft%dlb_control%gradients))
THEN
4175 DEALLOCATE (mixed_cdft%dlb_control%gradients)
4177 IF (mixed_cdft%is_special)
THEN
4178 DO j = 1,
SIZE(mixed_cdft%dlb_control%sendbuff)
4179 IF (
ASSOCIATED(mixed_cdft%dlb_control%sendbuff(j)%cavity))
THEN
4180 DEALLOCATE (mixed_cdft%dlb_control%sendbuff(j)%cavity)
4182 IF (
ASSOCIATED(mixed_cdft%dlb_control%sendbuff(j)%weight))
THEN
4183 DEALLOCATE (mixed_cdft%dlb_control%sendbuff(j)%weight)
4185 IF (
ASSOCIATED(mixed_cdft%dlb_control%sendbuff(j)%gradients))
THEN
4186 DEALLOCATE (mixed_cdft%dlb_control%sendbuff(j)%gradients)
4189 DEALLOCATE (mixed_cdft%dlb_control%sendbuff)
4191 DEALLOCATE (req_send, req_recv)
4192 ELSE IF (mixed_cdft%dlb_control%recv_work)
THEN
4193 IF (should_communicate)
THEN
4196 IF (
ASSOCIATED(mixed_cdft%dlb_control%cavity))
THEN
4197 DEALLOCATE (mixed_cdft%dlb_control%cavity)
4199 IF (
ASSOCIATED(mixed_cdft%dlb_control%weight))
THEN
4200 DEALLOCATE (mixed_cdft%dlb_control%weight)
4202 IF (
ASSOCIATED(mixed_cdft%dlb_control%gradients))
THEN
4203 DEALLOCATE (mixed_cdft%dlb_control%gradients)
4205 IF (mixed_cdft%is_special)
THEN
4206 DO j = 1,
SIZE(mixed_cdft%dlb_control%sendbuff)
4207 IF (
ASSOCIATED(mixed_cdft%dlb_control%sendbuff(j)%cavity))
THEN
4208 DEALLOCATE (mixed_cdft%dlb_control%sendbuff(j)%cavity)
4210 IF (
ASSOCIATED(mixed_cdft%dlb_control%sendbuff(j)%weight))
THEN
4211 DEALLOCATE (mixed_cdft%dlb_control%sendbuff(j)%weight)
4213 IF (
ASSOCIATED(mixed_cdft%dlb_control%sendbuff(j)%gradients))
THEN
4214 DEALLOCATE (mixed_cdft%dlb_control%sendbuff(j)%gradients)
4217 DEALLOCATE (mixed_cdft%dlb_control%sendbuff)
4219 DEALLOCATE (req_send)
4220 ELSE IF (any(mixed_cdft%dlb_control%recv_work_repl))
THEN
4222 DEALLOCATE (req_recv)
4225 IF (mixed_cdft%dlb)
THEN
4226 CALL force_env%para_env%sum(work)
4227 CALL force_env%para_env%sum(work_dlb)
4228 IF (.NOT.
ASSOCIATED(mixed_cdft%dlb_control%prediction_error))
THEN
4229 ALLOCATE (mixed_cdft%dlb_control%prediction_error(force_env%para_env%num_pe))
4231 mixed_cdft%dlb_control%prediction_error = mixed_cdft%dlb_control%expected_work - work
4232 IF (debug_this_module .AND. iounit > 0)
THEN
4233 DO i = 1,
SIZE(work, 1)
4234 WRITE (iounit,
'(A,I10,I10,I10)') &
4235 'Work', work(i), work_dlb(i), mixed_cdft%dlb_control%expected_work(i)
4238 DEALLOCATE (work, work_dlb, mixed_cdft%dlb_control%expected_work)
4240 NULLIFY (gradients, weight, cavity)
4241 IF (
ALLOCATED(coefficients))
THEN
4242 DEALLOCATE (coefficients)
4245 DEALLOCATE (ds_dr_j)
4246 DEALLOCATE (ds_dr_i)
4247 DEALLOCATE (d_sum_pm_dr)
4248 DEALLOCATE (d_sum_const_dr)
4249 DEALLOCATE (dp_i_drj)
4250 DEALLOCATE (dp_i_dri)
4252 IF (store_vectors)
THEN
4253 DEALLOCATE (pair_dist_vecs)
4257 IF (
ALLOCATED(is_constraint))
THEN
4258 DEALLOCATE (is_constraint)
4262 DEALLOCATE (cell_functions)
4263 DEALLOCATE (skip_me)
4264 IF (
ALLOCATED(completed))
THEN
4265 DEALLOCATE (completed)
4267 IF (
ASSOCIATED(nsent))
THEN
4270 IF (store_vectors)
THEN
4271 DEALLOCATE (distances)
4272 DEALLOCATE (distance_vecs)
4273 DEALLOCATE (position_vecs)
4275 IF (
ASSOCIATED(req_send))
THEN
4276 DEALLOCATE (req_send)
4278 IF (
ASSOCIATED(req_recv))
THEN
4279 DEALLOCATE (req_recv)
4282 "MIXED%MIXED_CDFT%PRINT%PROGRAM_RUN_INFO")
4283 CALL timestop(handle)
4285 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, nrow, ncol, set_zero)
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, zeff, stride, max_file_size_mb, 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, cell_ref, use_ref_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, mimic, 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, matrix_vhxc, 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, xcint_weights, 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.