(git:0a7030e)
Loading...
Searching...
No Matches
mo_window.F
Go to the documentation of this file.
1!--------------------------------------------------------------------------------------------------!
2! CP2K: A general program to perform molecular dynamics simulations !
3! Copyright 2000-2026 CP2K developers group <https://cp2k.org> !
4! !
5! SPDX-License-Identifier: GPL-2.0-or-later !
6!--------------------------------------------------------------------------------------------------!
7
8! **************************************************************************************************
9!> \brief Common selection and union operations for contiguous molecular-orbital windows.
10! **************************************************************************************************
12 USE kinds, ONLY: dp
13#include "./base/base_uses.f90"
14
15 IMPLICIT NONE
16
17 PRIVATE
18
19 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'mo_window'
20
22 INTEGER :: first_mo = 1
23 INTEGER :: last_mo = 0
24 END TYPE mo_window_type
25
27
28CONTAINS
29
30! **************************************************************************************************
31!> \brief Selects one contiguous MO window from an ordered reference spectrum.
32!>
33!> The input spectrum is supplied by the caller because different workflows may store more
34!> entries than the number of physical MOs to which a cutoff applies. The returned bounds are
35!> absolute, one-based indices in the caller's MO numbering.
36!> \param eigenvalues Reference eigenvalues for one spin channel.
37!> \param n_mo Number of physical MOs covered by the reference spectrum.
38!> \param n_occ Number of occupied MOs in that channel.
39!> \param cutoff_occ Occupied-state energy window; non-positive means no occupied cutoff.
40!> \param cutoff_empty Empty-state energy window; non-positive means no empty-state cutoff.
41!> \param window Selected absolute MO window (OUT).
42! **************************************************************************************************
43 SUBROUTINE determine_mo_window(eigenvalues, n_mo, n_occ, cutoff_occ, cutoff_empty, window)
44 REAL(kind=dp), DIMENSION(:), INTENT(IN) :: eigenvalues
45 INTEGER, INTENT(IN) :: n_mo, n_occ
46 REAL(kind=dp), INTENT(IN) :: cutoff_occ, cutoff_empty
47 TYPE(mo_window_type), INTENT(OUT) :: window
48
49 INTEGER :: i
50
51 IF (n_mo < 1 .OR. n_mo > SIZE(eigenvalues)) THEN
52 CALL cp_abort(__location__, "determine_mo_window: invalid number of physical MOs")
53 END IF
54 IF (n_occ < 1 .OR. n_occ >= n_mo) THEN
55 CALL cp_abort(__location__, "determine_mo_window: invalid occupied-state boundary")
56 END IF
57
58 window%first_mo = 1
59 window%last_mo = n_mo
60
61 IF (cutoff_occ > 0.0_dp .OR. cutoff_empty > 0.0_dp) THEN
62 DO i = 2, n_mo
63 IF (eigenvalues(i) < eigenvalues(i - 1)) THEN
64 CALL cp_abort(__location__, &
65 "determine_mo_window: reference eigenvalues are not ascending. "// &
66 "Use the DFT/SCF energy axis; the G0W0 axis is not ordered.")
67 END IF
68 END DO
69
70 IF (cutoff_occ > 0.0_dp) THEN
71 DO i = 1, n_occ
72 IF (eigenvalues(n_occ) - eigenvalues(i) <= cutoff_occ) THEN
73 window%first_mo = i
74 EXIT
75 END IF
76 END DO
77 END IF
78
79 IF (cutoff_empty > 0.0_dp) THEN
80 DO i = n_occ + 1, n_mo
81 IF (eigenvalues(i) - eigenvalues(n_occ + 1) > cutoff_empty) THEN
82 window%last_mo = i - 1
83 EXIT
84 END IF
85 END DO
86 END IF
87 END IF
88
89 END SUBROUTINE determine_mo_window
90
91! **************************************************************************************************
92!> \brief Forms the smallest contiguous window covering all supplied spin windows.
93!> \param spin_windows Per-spin absolute MO windows.
94!> \param combined_window Union of the supplied windows (OUT).
95!> \param windows_differ True if at least two input windows have different bounds (OUT).
96! **************************************************************************************************
97 SUBROUTINE combine_mo_windows(spin_windows, combined_window, windows_differ)
98 TYPE(mo_window_type), DIMENSION(:), INTENT(IN) :: spin_windows
99 TYPE(mo_window_type), INTENT(OUT) :: combined_window
100 LOGICAL, INTENT(OUT) :: windows_differ
101
102 INTEGER :: i
103
104 IF (SIZE(spin_windows) < 1) THEN
105 CALL cp_abort(__location__, "combine_mo_windows: no spin windows supplied")
106 END IF
107
108 combined_window%first_mo = spin_windows(1)%first_mo
109 combined_window%last_mo = spin_windows(1)%last_mo
110 windows_differ = .false.
111
112 DO i = 2, SIZE(spin_windows)
113 combined_window%first_mo = min(combined_window%first_mo, spin_windows(i)%first_mo)
114 combined_window%last_mo = max(combined_window%last_mo, spin_windows(i)%last_mo)
115 windows_differ = windows_differ .OR. &
116 spin_windows(i)%first_mo /= spin_windows(1)%first_mo .OR. &
117 spin_windows(i)%last_mo /= spin_windows(1)%last_mo
118 END DO
119
120 END SUBROUTINE combine_mo_windows
121
122END MODULE mo_window
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
Common selection and union operations for contiguous molecular-orbital windows.
Definition mo_window.F:11
subroutine, public combine_mo_windows(spin_windows, combined_window, windows_differ)
Forms the smallest contiguous window covering all supplied spin windows.
Definition mo_window.F:98
subroutine, public determine_mo_window(eigenvalues, n_mo, n_occ, cutoff_occ, cutoff_empty, window)
Selects one contiguous MO window from an ordered reference spectrum.
Definition mo_window.F:44