31 COMPLEX(KIND=dp),
INTENT(IN) ::
character(:), table(:, :)
32 INTEGER,
INTENT(OUT) :: multiplicities(:)
33 REAL(kind=
dp),
INTENT(IN) :: tolerance
34 INTEGER,
INTENT(OUT) :: status
36 COMPLEX(KIND=dp) :: value
37 INTEGER :: dimension, i, j, nirrep, order, total
41 order =
SIZE(character)
42 nirrep =
SIZE(table, 2)
43 IF (order < 1 .OR. order > 1024 .OR. nirrep < 1 .OR.
SIZE(table, 1) /= order)
RETURN
44 IF (
SIZE(multiplicities) /= nirrep .OR. tolerance <= 0.0_dp)
RETURN
45 IF (.NOT. ieee_is_finite(tolerance))
RETURN
46 IF (.NOT. all(ieee_is_finite(real(
CHARACTER,
dp)))) return
47 IF (.NOT. all(ieee_is_finite(aimag(character))))
RETURN
48 IF (.NOT. all(ieee_is_finite(real(table,
dp))))
RETURN
49 IF (.NOT. all(ieee_is_finite(aimag(table))))
RETURN
50 IF (maxval(abs(table)) > real(order,
dp) + tolerance)
RETURN
51 IF (maxval(abs(character)) > 1.e6_dp)
RETURN
54 dimension = nint(real(table(1, i),
dp))
55 IF (dimension < 1 .OR. dimension > order)
RETURN
56 IF (abs(table(1, i) - dimension) > tolerance)
RETURN
57 total = total + dimension**2
58 IF (total > order)
RETURN
60 value = sum(conjg(table(:, i))*table(:, j))/real(order,
dp)
61 IF (i == j)
value =
value - 1.0_dp
62 IF (abs(
value) > tolerance)
RETURN
65 IF (total /= order)
RETURN
68 value = sum(conjg(table(:, i))*character)/real(order,
dp)
69 j = nint(real(
value,
dp))
70 IF (j < 0 .OR. abs(
value - j) > tolerance)
RETURN
73 IF (maxval(abs(matmul(table, cmplx(multiplicities, 0,
dp)) - character)) > tolerance)
RETURN
94 tolerance, energy_tolerance, counts, error, energy_error, status, diagnostics)
95 COMPLEX(KIND=dp),
INTENT(IN) :: metric(:, :), coeff(:, :)
96 INTEGER,
INTENT(IN) :: mapping(:)
97 COMPLEX(KIND=dp),
INTENT(IN) :: phase(:)
98 REAL(kind=
dp),
INTENT(IN) :: energies(:)
99 LOGICAL,
INTENT(IN) :: check_tr
100 REAL(kind=
dp),
INTENT(IN) :: tolerance, energy_tolerance
101 INTEGER,
INTENT(OUT) :: counts(2)
102 REAL(kind=
dp),
INTENT(OUT) :: error, energy_error
103 INTEGER,
INTENT(OUT) :: status
104 REAL(kind=
dp),
INTENT(OUT),
OPTIONAL :: diagnostics(4)
106 COMPLEX(KIND=dp) :: characters(2), table(2, 2)
107 COMPLEX(KIND=dp),
ALLOCATABLE :: pc(:, :), projected(:, :), sc(:, :), &
108 trc(:, :), work(:, :)
109 INTEGER :: first, i, j, last, nao, nspin, rank, s
110 REAL(kind=
dp) :: metric_scale
115 energy_error = huge(1.0_dp)
116 IF (
PRESENT(diagnostics)) diagnostics = huge(1.0_dp)
117 nao =
SIZE(metric, 1)
118 rank =
SIZE(coeff, 2)
119 IF (nao < 1 .OR. rank < 1 .OR.
SIZE(metric, 2) /= nao)
RETURN
120 IF (mod(
SIZE(coeff, 1), nao) /= 0)
RETURN
121 nspin =
SIZE(coeff, 1)/nao
122 IF (nspin < 1 .OR. nspin > 2)
RETURN
123 IF (check_tr .AND. (nspin /= 2 .OR. mod(rank, 2) /= 0))
RETURN
124 IF (
SIZE(mapping) /= nao .OR.
SIZE(phase) /= nao .OR.
SIZE(energies) /= rank)
RETURN
125 IF (tolerance <= 0.0_dp .OR. energy_tolerance <= 0.0_dp)
RETURN
126 IF (.NOT. ieee_is_finite(tolerance) .OR. .NOT. ieee_is_finite(energy_tolerance))
RETURN
127 IF (.NOT. all(ieee_is_finite(real(metric,
dp))) .OR. .NOT. all(ieee_is_finite(aimag(metric))))
RETURN
128 IF (.NOT. all(ieee_is_finite(real(coeff,
dp))) .OR. .NOT. all(ieee_is_finite(aimag(coeff))))
RETURN
129 IF (.NOT. all(ieee_is_finite(real(phase,
dp))) .OR. .NOT. all(ieee_is_finite(aimag(phase))))
RETURN
130 IF (.NOT. all(ieee_is_finite(energies)))
RETURN
131 IF (any(mapping < 1) .OR. any(mapping > nao))
RETURN
132 IF (any(abs(abs(phase) - 1.0_dp) > tolerance))
RETURN
134 IF (mapping(mapping(i)) /= i)
RETURN
135 IF (abs(phase(i)*phase(mapping(i)) - 1.0_dp) > tolerance)
RETURN
137 metric_scale = max(1.0_dp, maxval(abs(metric)))
138 error = maxval(abs(metric - conjg(transpose(metric))))/metric_scale
141 error = max(error, abs(conjg(phase(i))*metric(mapping(i), mapping(j))*phase(j) - metric(i, j))/ &
145 IF (
PRESENT(diagnostics)) diagnostics(1) = error
146 ALLOCATE (sc(nao*nspin, rank), pc(nao*nspin, rank), projected(rank, rank), work(rank, rank))
150 sc(first + 1:last, :) = matmul(metric, coeff(first + 1:last, :))
152 pc(first + mapping(i), :) = phase(i)*coeff(first + i, :)
155 work(:, :) = matmul(conjg(transpose(coeff)), sc)
157 work(i, i) = work(i, i) - 1.0_dp
159 error = max(error, maxval(abs(work)))
160 IF (
PRESENT(diagnostics)) diagnostics(2) = maxval(abs(work))
161 projected(:, :) = matmul(conjg(transpose(sc)), pc)
162 IF (.NOT. all(ieee_is_finite(real(projected,
dp))))
RETURN
163 IF (.NOT. all(ieee_is_finite(aimag(projected))))
RETURN
164 work(:, :) = matmul(conjg(transpose(projected)), projected)
166 work(i, i) = work(i, i) - 1.0_dp
168 error = max(error, maxval(abs(work)), maxval(abs(projected - conjg(transpose(projected)))))
169 IF (
PRESENT(diagnostics)) diagnostics(3) = max(maxval(abs(work)), &
170 maxval(abs(projected - conjg(transpose(projected)))))
171 IF (
PRESENT(diagnostics))
THEN
172 IF (.NOT. check_tr) diagnostics(4) = 0.0_dp
174 energy_error = 0.0_dp
177 energy_error = max(energy_error, abs(projected(i, j)*(energies(i) - energies(j))))
180 characters(1) = cmplx(rank, 0,
dp)
181 characters(2) = cmplx(0, 0,
dp)
183 characters(2) = characters(2) + projected(i, i)
185 table(:, 1) = cmplx([1, 1], 0,
dp)
186 table(:, 2) = cmplx([1, -1], 0,
dp)
188 IF (status /= 0)
RETURN
192 error = max(error, maxval(abs(aimag(metric)))/max(1.0_dp, maxval(abs(metric))))
193 ALLOCATE (trc(2*nao, rank))
194 trc(:nao, :) = conjg(coeff(nao + 1:, :))
195 trc(nao + 1:, :) = -conjg(coeff(:nao, :))
196 projected(:, :) = matmul(conjg(transpose(sc)), trc)
197 work(:, :) = matmul(conjg(transpose(projected)), projected)
199 work(i, i) = work(i, i) - 1.0_dp
201 error = max(error, maxval(abs(work)), maxval(abs(projected + transpose(projected))))
202 IF (
PRESENT(diagnostics)) diagnostics(4) = max(maxval(abs(work)), &
203 maxval(abs(projected + transpose(projected))))
206 energy_error = max(energy_error, abs(projected(i, j)*(energies(i) - energies(j))))
209 IF (any(mod(counts, 2) /= 0))
RETURN
211 IF (.NOT. ieee_is_finite(error) .OR. .NOT. ieee_is_finite(energy_error))
RETURN
212 IF (error > tolerance .OR. energy_error > energy_tolerance)
RETURN