Skip to content

Commit 5db81cc

Browse files
authored
Propagate error in Broyden mixing up to SCF iterations (#78)
1 parent e91b79d commit 5db81cc

2 files changed

Lines changed: 19 additions & 12 deletions

File tree

src/tblite/scf/broyden.f90

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919

2020
!> Implementation of a modified Broyden mixing
2121
module tblite_scf_broyden
22-
use mctc_env, only : wp
22+
use mctc_env, only : wp, error_type, fatal_error
2323
use tblite_lapack, only : getrf, getrs
2424
implicit none
2525
private
@@ -131,14 +131,21 @@ subroutine diff_1d(self, qvec)
131131
self%idif = self%idif + size(qvec)
132132
end subroutine diff_1d
133133

134-
subroutine next(self)
134+
subroutine next(self, error)
135135
class(broyden_mixer), intent(inout) :: self
136+
type(error_type), allocatable, intent(out) :: error
137+
138+
integer :: info
139+
136140
self%iset = 0
137141
self%idif = 0
138142
self%iget = 0
139143
self%iter = self%iter + 1
140144
call broyden(self%ndim, self%q_in, self%qlast_in, self%dq, self%dqlast, &
141-
& self%iter, self%memory, self%damp, self%omega, self%df, self%u, self%a)
145+
& self%iter, self%memory, self%damp, self%omega, self%df, self%u, self%a, info)
146+
if (info /= 0) then
147+
call fatal_error(error, "Broyden mixing failed to obtain next iteration")
148+
end if
142149
end subroutine next
143150

144151
subroutine get_2d(self, qvec)
@@ -164,7 +171,7 @@ subroutine get_1d(self, qvec)
164171
self%iget = self%iget + size(qvec)
165172
end subroutine get_1d
166173

167-
subroutine broyden(n, q, qlast, dq, dqlast, iter, memory, alpha, omega, df, u, a)
174+
subroutine broyden(n, q, qlast, dq, dqlast, iter, memory, alpha, omega, df, u, a, info)
168175
integer, intent(in) :: n
169176
integer, intent(in) :: iter
170177
integer, intent(in) :: memory
@@ -177,11 +184,13 @@ subroutine broyden(n, q, qlast, dq, dqlast, iter, memory, alpha, omega, df, u, a
177184
real(wp), intent(inout) :: a(memory, memory)
178185
real(wp), intent(inout) :: omega(memory)
179186
real(wp), intent(in) :: alpha
187+
integer, intent(out) :: info
180188

181189
real(wp), allocatable :: beta(:,:), c(:, :)
182190
integer :: i, it1
183191
real(wp) :: inv, omega0, minw, maxw, wfac
184192

193+
info = 0
185194
it1 = iter - 1
186195

187196
! set parameters
@@ -233,7 +242,8 @@ subroutine broyden(n, q, qlast, dq, dqlast, iter, memory, alpha, omega, df, u, a
233242
end do
234243

235244
! build beta^-1
236-
call lineq(beta, c)
245+
call lineq(beta, c, info)
246+
if (info /= 0) return
237247

238248
! Build |u>
239249
u(:, it1) = alpha * df(:, it1) + inv * (q-qlast) !!!
@@ -251,11 +261,11 @@ subroutine broyden(n, q, qlast, dq, dqlast, iter, memory, alpha, omega, df, u, a
251261

252262
end subroutine broyden
253263

254-
subroutine lineq(a, c)
264+
subroutine lineq(a, c, info)
255265
real(wp), intent(inout) :: a(:, :)
256266
real(wp), intent(inout) :: c(:, :)
267+
integer, intent(out) :: info
257268

258-
integer info
259269
integer, allocatable :: ipiv(:)
260270

261271
allocate(ipiv(size(a, 1)))
@@ -265,10 +275,6 @@ subroutine lineq(a, c)
265275
! generate inverse of a matrix given its LU decomposition
266276
call getrs(a, c, ipiv, info, trans="t")
267277
endif
268-
if (info /= 0)then
269-
error stop "Error in Broyden matrix inversion!"
270-
endif
271-
272278
end subroutine lineq
273279

274280
pure function get_error(self) result(error)

src/tblite/scf/iterator.f90

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,8 @@ subroutine next_scf(iscf, mol, bas, wfn, solver, mixer, info, coulomb, dispersio
8787
real(wp) :: ts
8888

8989
if (iscf > 0) then
90-
call mixer%next
90+
call mixer%next(error)
91+
if (allocated(error)) return
9192
call get_mixer(mixer, bas, wfn, info)
9293
end if
9394

0 commit comments

Comments
 (0)