Octopus
lda_u_mixer.F90
Go to the documentation of this file.
1!! Copyright (C) 2016 N. Tancogne-Dejean
2!!
3!! This program is free software; you can redistribute it and/or modify
4!! it under the terms of the GNU General Public License as published by
5!! the Free Software Foundation; either version 2, or (at your option)
6!! any later version.
7!!
8!! This program is distributed in the hope that it will be useful,
9!! but WITHOUT ANY WARRANTY; without even the implied warranty of
10!! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11!! GNU General Public License for more details.
12!!
13!! You should have received a copy of the GNU General Public License
14!! along with this program; if not, write to the Free Software
15!! Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
16!! 02110-1301, USA.
17!!
18
19#include "global.h"
20
22 use debug_oct_m
23 use global_oct_m
24 use lda_u_oct_m
26 use mix_oct_m
31 use types_oct_m
32
33 implicit none
34
35 private
36
37 public :: &
46
47 type lda_u_mixer_t
48 private
49 integer :: occsize
50 logical :: realstates
51 logical :: apply = .false.
52 logical :: mixU = .false.
53
54 real(real64), allocatable :: dtmp_occ(:,:), tmpU(:,:)
55 complex(real64), allocatable :: ztmp_occ(:,:)
56
57 type(mixfield_t) :: mixfield_occ, mixfield_U
58 end type lda_u_mixer_t
59
60contains
61
62 ! ---------------------------------------------------------
63 subroutine lda_u_mixer_init_auxmixer(this, namespace, mixer, smix, st)
64 type(lda_u_t), intent(in) :: this
65 type(namespace_t), intent(in) :: namespace
66 type(lda_u_mixer_t), intent(inout) :: mixer
67 type(mix_t), intent(inout) :: smix
68 type(states_elec_t), intent(in) :: st
69
70 integer :: dim1
71
72 if (this%level == dft_u_none) return
74
75 dim1 = this%maxnorbs*this%maxnorbs*this%nspins*this%norbsets
76 if (this%level == dft_u_acbn0) then
77 dim1 = dim1*2
78 if (this%intersite) then
79 dim1 = dim1 + 2*this%maxnorbs*this%maxnorbs*this%nspins*this%norbsets*this%maxneighbors
80 end if
81 end if
82
83 if (states_are_real(st)) then
84 call mixfield_init(smix, mixer%mixfield_occ, dim1, 1, mix_d3(smix), type_float)
85 mixer%realstates = .true.
86 else
87 call mixfield_init(smix, mixer%mixfield_occ, dim1, 1, mix_d3(smix), type_cmplx)
88 mixer%realstates = .false.
89 end if
90 call mixfield_clear(mix_scheme(smix), mixer%mixfield_occ)
91 call mix_add_auxmixfield(namespace, smix, mixer%mixfield_occ)
92
93 if (this%level == dft_u_acbn0) then
94 call mixfield_init(smix, mixer%mixfield_U, this%norbsets, 1, mix_d3(smix), type_float)
95 call mixfield_clear(mix_scheme(smix), mixer%mixfield_U)
96 call mix_add_auxmixfield(namespace, smix, mixer%mixfield_U)
97 mixer%mixU = .true.
98 else
99 mixer%mixU = .false.
100 end if
101
103 end subroutine lda_u_mixer_init_auxmixer
104
105
106 ! ---------------------------------------------------------
107 subroutine lda_u_mixer_init(this, mixer, st)
108 type(lda_u_t), intent(in) :: this
109 type(lda_u_mixer_t), intent(inout) :: mixer
110 type(states_elec_t), intent(in) :: st
111
112 if (this%level == dft_u_none) then
113 mixer%apply = .false.
114 return
115 end if
116
117 push_sub(lda_u_mixer_init)
118
119 mixer%apply = .true.
120
121 mixer%occsize = this%maxnorbs*this%maxnorbs*this%nspins*this%norbsets
122 if (this%level == dft_u_acbn0) then
123 mixer%occsize = mixer%occsize*2
124 if (this%intersite) then
125 mixer%occsize = mixer%occsize + 2*this%maxnorbs*this%maxnorbs*this%nspins*this%norbsets*this%maxneighbors
126 end if
127 end if
128
129 if (states_are_real(st)) then
130 safe_allocate(mixer%dtmp_occ(1:mixer%occsize, 1))
131 else
132 safe_allocate(mixer%ztmp_occ(1:mixer%occsize, 1))
133 end if
134
135 if (this%level == dft_u_acbn0) then
136 safe_allocate(mixer%tmpU(1:this%norbsets, 1))
137 end if
138
139 pop_sub(lda_u_mixer_init)
140 end subroutine lda_u_mixer_init
141
142 ! ---------------------------------------------------------
143 subroutine lda_u_mixer_clear(mixer, smix)
144 type(lda_u_mixer_t), intent(inout) :: mixer
145 type(mix_t), intent(inout) :: smix
146
147 if (.not. mixer%apply) return
149
150 call mixfield_clear(mix_scheme(smix), mixer%mixfield_occ)
151 if (mixer%mixU) call mixfield_clear(mix_scheme(smix), mixer%mixfield_U)
152
153 pop_sub(lda_u_mixer_clear)
154 end subroutine lda_u_mixer_clear
155
156 ! ---------------------------------------------------------
157 subroutine lda_u_mixer_end(mixer, smix)
158 type(lda_u_mixer_t), intent(inout) :: mixer
159 type(mix_t), intent(inout) :: smix
160
161 if (.not. mixer%apply) return
162 push_sub(lda_u_mixer_end)
163
164 safe_deallocate_a(mixer%dtmp_occ)
165 safe_deallocate_a(mixer%ztmp_occ)
166 safe_deallocate_a(mixer%tmpU)
167
168 call mixfield_end(smix,mixer%mixfield_occ)
169 if (mixer%mixU) call mixfield_end(smix, mixer%mixfield_U)
170
171 pop_sub(lda_u_mixer_end)
172 end subroutine lda_u_mixer_end
173
174 ! ---------------------------------------------------------
175 subroutine lda_u_mixer_set_vout(this, mixer)
176 type(lda_u_t), intent(in) :: this
177 type(lda_u_mixer_t), intent(inout) :: mixer
178
179 if (.not. mixer%apply) return
180 push_sub(lda_u_mixer_set_vout)
181
182 if (mixer%realstates) then
183 call dlda_u_get_occupations(this, mixer%dtmp_occ(1:mixer%occsize, 1))
184 call mixfield_set_vout(mixer%mixfield_occ, mixer%dtmp_occ)
185 else
186 call zlda_u_get_occupations(this, mixer%ztmp_occ(1:mixer%occsize, 1))
187 call mixfield_set_vout(mixer%mixfield_occ, mixer%ztmp_occ)
188 end if
189
190 if (this%level == dft_u_acbn0) then
191 call lda_u_get_effectiveu(this, mixer%tmpU(1:this%norbsets, 1))
192 call mixfield_set_vout(mixer%mixfield_U, mixer%tmpU)
193 end if
194
195 pop_sub(lda_u_mixer_set_vout)
196 end subroutine lda_u_mixer_set_vout
197
198 ! ---------------------------------------------------------
199 subroutine lda_u_mixer_set_vin(this, mixer)
200 type(lda_u_t), intent(in) :: this
201 type(lda_u_mixer_t), intent(inout) :: mixer
202
203 if (.not. mixer%apply) return
204 push_sub(lda_u_mixer_set_vin)
205
206 if (mixer%realstates) then
207 call dlda_u_get_occupations(this, mixer%dtmp_occ(1:mixer%occsize, 1))
208 call mixfield_set_vin(mixer%mixfield_occ, mixer%dtmp_occ)
209 else
210 call zlda_u_get_occupations(this, mixer%ztmp_occ(1:mixer%occsize, 1))
211 call mixfield_set_vin(mixer%mixfield_occ, mixer%ztmp_occ)
212 end if
213
214 if (this%level == dft_u_acbn0) then
215 call lda_u_get_effectiveu(this, mixer%tmpU(1:this%norbsets, 1))
216 call mixfield_set_vin(mixer%mixfield_U, mixer%tmpU)
217 end if
218
219 pop_sub(lda_u_mixer_set_vin)
220 end subroutine lda_u_mixer_set_vin
221
222 ! ---------------------------------------------------------
223 subroutine lda_u_mixer_get_vnew(this, mixer, st)
224 type(lda_u_t), intent(inout) :: this
225 type(lda_u_mixer_t), intent(inout) :: mixer
226 type(states_elec_t), intent(in) :: st
227
228 if (.not. mixer%apply) return
229 push_sub(lda_u_mixer_get_vnew)
230
231 if (this%level == dft_u_acbn0) then
232 call mixfield_get_vnew(mixer%mixfield_U, mixer%tmpU)
233 call lda_u_set_effectiveu(this, mixer%tmpU(1:this%norbsets, 1))
234 end if
235
237 if (mixer%realstates) then
238 call mixfield_get_vnew(mixer%mixfield_occ, mixer%dtmp_occ)
239 call dlda_u_set_occupations(this, mixer%dtmp_occ(1:mixer%occsize, 1))
240 call dlda_u_update_potential(this, st)
241 else
242 call mixfield_get_vnew(mixer%mixfield_occ, mixer%ztmp_occ)
243 call zlda_u_set_occupations(this, mixer%ztmp_occ(1:mixer%occsize, 1))
244 call zlda_u_update_potential(this, st)
245 end if
246
247 pop_sub(lda_u_mixer_get_vnew)
248 end subroutine lda_u_mixer_get_vnew
249
251end module lda_u_mixer_oct_m
subroutine, public lda_u_mixer_set_vin(this, mixer)
subroutine, public lda_u_mixer_init(this, mixer, st)
subroutine, public lda_u_mixer_clear(mixer, smix)
subroutine, public lda_u_mixer_init_auxmixer(this, namespace, mixer, smix, st)
subroutine, public lda_u_mixer_get_vnew(this, mixer, st)
subroutine, public lda_u_mixer_set_vout(this, mixer)
subroutine, public lda_u_mixer_end(mixer, smix)
subroutine, public lda_u_get_effectiveu(this, Ueff)
Definition: lda_u.F90:917
subroutine, public lda_u_set_effectiveu(this, Ueff)
Definition: lda_u.F90:901
integer, parameter, public dft_u_none
Definition: lda_u.F90:201
subroutine, public dlda_u_get_occupations(this, occ)
Definition: lda_u.F90:3470
subroutine, public zlda_u_update_potential(this, st)
This routine computes the potential that, once multiplied by the projector Pmm' and summed over m and...
Definition: lda_u.F90:4250
subroutine, public dlda_u_set_occupations(this, occ)
Definition: lda_u.F90:3413
integer, parameter, public dft_u_acbn0
Definition: lda_u.F90:201
subroutine, public zlda_u_get_occupations(this, occ)
Definition: lda_u.F90:5492
subroutine, public dlda_u_update_potential(this, st)
This routine computes the potential that, once multiplied by the projector Pmm' and summed over m and...
Definition: lda_u.F90:2279
subroutine, public zlda_u_set_occupations(this, occ)
Definition: lda_u.F90:5435
subroutine, public mixfield_end(smix, mixfield)
Deallocate all arrays of a mixfield instance.
Definition: mix.F90:906
integer pure function, public mix_scheme(this)
Definition: mix.F90:806
subroutine, public mixfield_init(smix, mixfield, d1, d2, d3, func_type)
Initialise all attributes of a mixfield instance.
Definition: mix.F90:860
subroutine, public mix_add_auxmixfield(namespace, smix, mixfield)
Definition: mix.F90:841
subroutine, public mixfield_clear(scheme, mixfield)
Zero all potential and field attributes of a mixfield instance.
Definition: mix.F90:943
integer pure function, public mix_d3(this)
Definition: mix.F90:812
pure logical function, public states_are_real(st)
type(type_t), parameter, public type_cmplx
Definition: types.F90:134
type(type_t), parameter, public type_float
Definition: types.F90:133
Class to describe DFT+U parameters.
Definition: lda_u.F90:214
God class for mixing.
Definition: mix.F90:214
The states_elec_t class contains all electronic wave functions.
int true(void)