The Elk Code
 
Loading...
Searching...
No Matches
mixbroyden.f90
Go to the documentation of this file.
1
2! Copyright (C) 2011 J. K. Dewhurst, S. Sharma and E. K. U. Gross.
3! This file is distributed under the terms of the GNU Lesser General Public
4! License. See the file COPYING for license details.
5
6subroutine mixbroyden(iscl,n,msd,alpha,w0,nu,mu,f,df,u,a,d)
7use modomp
8implicit none
9! arguments
10integer, intent(in) :: iscl,n,msd
11real(8), intent(in) :: alpha,w0
12real(8), intent(inout) :: nu(n),mu(n,2)
13real(8), intent(inout) :: f(n,2),df(n,msd)
14real(8), intent(inout) :: u(n,msd),a(msd,msd)
15real(8), intent(out) :: d
16! local variables
17integer jc,kp,kc,k,m
18integer info,nthd
19real(8) t1
20! automatic arrays
21integer ipiv(msd)
22real(8) c(msd),beta(msd,msd),gamma(msd),work(msd)
23! external functions
24real(8), external :: ddot
25if (n < 1) then
26 write(*,*)
27 write(*,'("Error(mixbroyden): n < 1 : ",I8)') n
28 write(*,*)
29 stop
30end if
31if (msd < 2) then
32 write(*,*)
33 write(*,'("Error(mixbroyden): msd < 2 : ",I8)') msd
34 write(*,*)
35 stop
36end if
37! initialise mixer
38if (iscl < 1) then
39 mu(1:n,1)=nu(1:n)
40 mu(1:n,2)=nu(1:n)
41 f(1:n,1)=0.d0
42 df(1:n,1)=0.d0
43 u(1:n,1)=0.d0
44 a(1:msd,1:msd)=0.d0
45 d=1.d0
46 return
47end if
48! current subspace dimension
49m=min(iscl+1,msd)
50! current index modulo m
51jc=mod(iscl,m)+1
52! previous index modulo 2
53kp=mod(iscl-1,2)+1
54! current index modulo 2
55kc=mod(iscl,2)+1
56f(1:n,kc)=nu(1:n)-mu(1:n,kp)
57d=sum(f(1:n,kc)**2)
58d=sqrt(d/dble(n))
59df(1:n,jc)=f(1:n,kc)-f(1:n,kp)
60t1=norm2(df(1:n,jc))
61if (t1 > 1.d-8) t1=1.d0/t1
62df(1:n,jc)=t1*df(1:n,jc)
63u(1:n,jc)=alpha*df(1:n,jc)+t1*(mu(1:n,kp)-mu(1:n,kc))
64call holdthd(2*m,nthd)
65!$OMP PARALLEL DEFAULT(SHARED) &
66!$OMP NUM_THREADS(nthd)
67!$OMP DO SCHEDULE(DYNAMIC)
68do k=1,m
69 c(k)=ddot(n,df(1,k),1,f(1,kc),1)
70end do
71!$OMP END DO NOWAIT
72!$OMP DO SCHEDULE(DYNAMIC)
73do k=1,m
74 a(k,jc)=ddot(n,df(1,k),1,df(1,jc),1)
75 a(jc,k)=a(k,jc)
76end do
77!$OMP END DO
78!$OMP END PARALLEL
79call freethd(nthd)
80beta(1:msd,1:msd)=a(1:msd,1:msd)
81do k=1,m
82 beta(k,k)=beta(k,k)+w0**2
83end do
84! invert beta
85call dgetrf(m,m,beta,msd,ipiv,info)
86if (info == 0) call dgetri(m,beta,msd,ipiv,work,m,info)
87if (info /= 0) then
88 write(*,*)
89 write(*,'("Error(mixbroyden): could not invert matrix")')
90 write(*,*)
91 stop
92end if
93do k=1,m
94 gamma(k)=sum(c(1:m)*beta(1:m,k))
95end do
96nu(1:n)=mu(1:n,kp)+alpha*f(1:n,kc)
97do k=1,m
98 t1=-gamma(k)
99 nu(1:n)=nu(1:n)+t1*u(1:n,k)
100end do
101mu(1:n,kc)=nu(1:n)
102end subroutine
103
subroutine mixbroyden(iscl, n, msd, alpha, w0, nu, mu, f, df, u, a, d)
Definition mixbroyden.f90:7
subroutine holdthd(nloop, nthd)
Definition modomp.f90:78
subroutine freethd(nthd)
Definition modomp.f90:106