Branch data Line data Source code
1 : :
2 : : #if defined HAVE_CONFIG_H
3 : : #include "config.h"
4 : : #endif
5 : :
6 : : #include "abi_common.h"
7 : :
8 : : module m_tdep_phi4
9 : :
10 : : use defs_basis
11 : : use m_errors
12 : : use m_abicore
13 : : use m_numeric_tools
14 : : use m_linalg_interfaces
15 : : use m_io_tools
16 : : use m_crystal, only : crystal_t
17 : : use m_tdep_dataset, only : atdep_dataset_type, MPI_enreg_type
18 : : use m_tdep_latt, only : Lattice_type
19 : : use m_tdep_shell, only : Shell_type
20 : : use m_tdep_sym, only : Symmetries_type
21 : : use m_tdep_sampling, only : tdep_Sampling_type
22 : : use m_tdep_solver, only : tdep_Solver_type
23 : : use m_tdep_model, only : tdep_Model_type
24 : : use m_tdep_constraints, only : Constraints_type
25 : :
26 : : implicit none
27 : :
28 : : public :: tdep_calc_ftot4
29 : : public :: tdep_calc_phi4ref
30 : : public :: tdep_write_phi4
31 : : public :: tdep_build_phi4_3333
32 : :
33 : : contains
34 : :
35 : : !====================================================================================================
36 : :
37 : 8 : subroutine tdep_calc_ftot4(Model,Invar,Shell4at,ucart,Sym)
38 : :
39 : : type(tdep_Model_type),intent(inout) :: Model
40 : : type(atdep_dataset_type),intent(in) :: Invar
41 : : type(Shell_type),intent(in) :: Shell4at
42 : : type(Symmetries_type),intent(in) :: Sym
43 : : double precision, intent(in) :: ucart(3,Invar%natom,Invar%my_nstep)
44 : :
45 : : integer :: iatom,jatom,katom,latom,isym,itrans,ishell,iatshell
46 : : integer :: ii,jj,kk,ll,istep
47 : 8 : double precision, allocatable :: Phi4_3333(:,:,:,:)
48 : 8 : double precision, allocatable :: ucart_blas(:)
49 : 8 : double precision, allocatable :: ftot4(:,:)
50 : :
51 [ + - + + : 976 : ABI_MALLOC(Phi4_3333,(3,3,3,3)) ; Phi4_3333(:,:,:,:)=0.d0
+ + + + +
+ ]
52 [ + - - + : 88760 : ABI_MALLOC(ftot4,(3*Invar%natom,Invar%my_nstep)); ftot4(:,:)=0.d0
+ - - + +
- + - + -
- + - + +
+ + + ]
53 [ + + ]: 1484 : do iatom=1,Invar%natom
54 [ + + ]: 9316 : do ishell=1,Shell4at%nshell
55 : : ! Build the 3x3x3x3 IFC of an atom in this shell
56 [ + + ]: 7832 : if (Shell4at%neighbours(iatom,ishell)%n_interactions.eq.0) cycle
57 [ + + ]: 252016 : do iatshell=1,Shell4at%neighbours(iatom,ishell)%n_interactions
58 : 243732 : jatom=Shell4at%neighbours(iatom,ishell)%atomj_in_shell(iatshell)
59 : 243732 : katom=Shell4at%neighbours(iatom,ishell)%atomk_in_shell(iatshell)
60 : 243732 : latom=Shell4at%neighbours(iatom,ishell)%atoml_in_shell(iatshell)
61 : 243732 : isym =Shell4at%neighbours(iatom,ishell)%sym_in_shell(iatshell)
62 : 243732 : itrans=Shell4at%neighbours(iatom,ishell)%transpose_in_shell(iatshell)
63 : 243732 : call tdep_build_phi4_3333(isym,Model%Phi4(:,:,:,:,ishell),Phi4_3333,Sym,itrans)
64 : : ! Calculation of the force components (third order)
65 [ + + ]: 5126204 : do istep=1,Invar%my_nstep
66 [ + + ]: 19742292 : do ii=1,3
67 [ + + ]: 63370320 : do jj=1,3
68 [ + + ]: 190110960 : do kk=1,3
69 [ + + ]: 570332880 : do ll=1,3
70 : : ftot4(3*(iatom-1)+ii,istep)=ftot4(3*(iatom-1)+ii,istep)+&
71 : 526461120 : & Phi4_3333(ii,jj,kk,ll)*ucart(jj,jatom,istep)*ucart(kk,katom,istep)*ucart(ll,latom,istep)
72 : : end do !ll
73 : : end do !kk
74 : : end do !jj
75 : : end do !ii
76 : : end do !istep
77 : : end do !iatshell
78 : : end do !ishell
79 : : end do !iatom
80 [ - + ]: 8 : ABI_FREE(Phi4_3333)
81 [ + + + + ]: 88728 : ftot4(:,:)=ftot4(:,:)/6.d0
82 : :
83 [ - + + - : 4460 : ABI_MALLOC(ucart_blas ,(3*Invar%natom)) ; ucart_blas (:)=0.d0
+ - + - -
+ + - +
+ ]
84 [ + + ]: 168 : do istep=1,Invar%my_nstep
85 [ + + ]: 88720 : ucart_blas(:)=0.d0
86 [ + + ]: 29680 : do jatom=1,Invar%natom
87 [ + + ]: 118240 : do jj=1,3
88 : 118080 : ucart_blas(3*(jatom-1)+jj)=ucart(jj,jatom,istep)
89 : : end do
90 : : end do
91 : : call DGEMM('T','N',1,1,3*Invar%natom,1./4.d0,ftot4(:,istep),3*Invar%natom,ucart_blas,&
92 : 160 : & 3*Invar%natom,0.d0,Model%Phi4UiUjUkUl(istep),3*Invar%natom)
93 : : Model%Forces(3*Invar%natom*(istep-1)+1:3*Invar%natom*istep)=&
94 [ + + ]: 88728 : & Model%Forces(3*Invar%natom*(istep-1)+1:3*Invar%natom*istep)-ftot4(:,istep)
95 : : end do
96 [ - + ]: 8 : ABI_FREE(ucart_blas)
97 [ - + ]: 8 : ABI_FREE(ftot4)
98 : :
99 : 8 : end subroutine tdep_calc_ftot4
100 : :
101 : : !=====================================================================================================
102 : 8 : subroutine tdep_calc_phi4ref(Solver,Shell4at,Phi4_ref)
103 : :
104 : : type(tdep_Solver_type),intent(in) :: Solver
105 : : type(Shell_type),intent(in) :: Shell4at
106 : : double precision, intent(inout) :: Phi4_ref(3,3,3,3,Shell4at%nshell)
107 : :
108 : : integer :: ishell,ncoeff,ncoeff_prev
109 : : integer :: ii,jj,kk,ll,kappa
110 : 8 : double precision, allocatable :: Phi4_coeff(:)
111 : :
112 [ - + + - : 566 : ABI_CALLOC(Phi4_coeff, (Solver%ncoeff4th))
+ - + - -
+ - + +
+ ]
113 [ + + ]: 550 : Phi4_coeff(:) = Solver%theta(Solver%ncoeff1st+Solver%ncoeff2nd+Solver%ncoeff3rd+1:Solver%ntotcoeff)
114 : :
115 [ + + ]: 54 : do ishell=1,Shell4at%nshell
116 : : ! Build the 3x3x3x3 IFC per shell
117 : 46 : ncoeff =Shell4at%ncoeff(ishell)
118 : 46 : ncoeff_prev=Shell4at%ncoeff_prev(ishell)
119 : 46 : kappa=0
120 [ + + ]: 184 : do ii=1,3
121 [ + + ]: 598 : do jj=1,3
122 [ + + ]: 1794 : do kk=1,3
123 [ + + ]: 5382 : do ll=1,3
124 : 3726 : kappa=kappa+1
125 [ + + ]: 48870 : Phi4_ref(ii,jj,kk,ll,ishell)=sum(Shell4at%proj(kappa,1:ncoeff,ishell)*Phi4_coeff(ncoeff_prev+1:ncoeff_prev+ncoeff))
126 : : end do
127 : : end do
128 : : end do
129 : : end do
130 : : ! Remove the rounding errors before writing (for non regression testing purposes)
131 [ + + ]: 192 : do ii=1,3
132 [ + + ]: 598 : do jj=1,3
133 [ + + ]: 1794 : do kk=1,3
134 [ + + ]: 5382 : do ll=1,3
135 [ + + ]: 4968 : if (abs(Phi4_ref(ii,jj,kk,ll,ishell)).lt.tol8) Phi4_ref(ii,jj,kk,ll,ishell)=zero
136 : : end do
137 : : end do
138 : : end do
139 : : end do
140 : : end do
141 : :
142 [ - + ]: 8 : ABI_FREE(Phi4_coeff)
143 : :
144 : 8 : end subroutine tdep_calc_phi4ref
145 : :
146 : : !=====================================================================================================
147 : 8 : subroutine tdep_write_phi4(distance,Invar,Phi4_ref,Shell4at,Sym)
148 : :
149 : : type(atdep_dataset_type),intent(in) :: Invar
150 : : type(Symmetries_type),intent(in) :: Sym
151 : : type(Shell_type),intent(in) :: Shell4at
152 : : double precision, intent(in) :: distance(Invar%natom,Invar%natom,4)
153 : : double precision, intent(in) :: Phi4_ref(3,3,3,3,Shell4at%nshell)
154 : :
155 : : integer :: ishell,isym,jatom,katom,latom
156 : : integer :: iatref,jatref,katref,latref,iatshell,itrans
157 : : integer :: ii,jj,kk
158 : : double precision :: tmp1,tmp2,tmp3
159 : 8 : double precision, allocatable :: Phi4_3333(:,:,:,:)
160 : :
161 : 8 : write(Invar%stdout,*) ' '
162 : 8 : write(Invar%stdout,*) '#############################################################################'
163 : 8 : write(Invar%stdout,*) '#### For each shell, list of coefficients (IFC), number of neighbours... ####'
164 : 8 : write(Invar%stdout,*) '#############################################################################'
165 : :
166 : : ! Write the IFCs in the data.out file (with others specifications:
167 : : ! number of atoms in a shell, Trace...)
168 [ + - + + : 976 : ABI_MALLOC(Phi4_3333,(3,3,3,3)) ; Phi4_3333(:,:,:,:)=0.d0
+ + + + +
+ ]
169 [ + + ]: 54 : do ishell=1,Shell4at%nshell
170 : 46 : iatref=Shell4at%iatref(ishell)
171 [ + - ]: 54 : if (Shell4at%neighbours(iatref,ishell)%n_interactions.ne.0) then
172 : 46 : jatref=Shell4at%jatref(ishell)
173 : 46 : katref=Shell4at%katref(ishell)
174 : 46 : latref=Shell4at%latref(ishell)
175 : 46 : write(Invar%stdout,'(a,i4,a,i4,a)') ' ======== NEW SHELL (ishell=',ishell,&
176 : 92 : & '): There are',Shell4at%neighbours(iatref,ishell)%n_interactions,' atoms on this shell'
177 [ + + ]: 1677 : do iatshell=1,Shell4at%neighbours(iatref,ishell)%n_interactions
178 : 1631 : jatom =Shell4at%neighbours(iatref,ishell)%atomj_in_shell(iatshell)
179 : 1631 : katom =Shell4at%neighbours(iatref,ishell)%atomk_in_shell(iatshell)
180 : 1631 : latom =Shell4at%neighbours(iatref,ishell)%atoml_in_shell(iatshell)
181 : 1631 : isym =Shell4at%neighbours(iatref,ishell)%sym_in_shell(iatshell)
182 : 1631 : itrans=Shell4at%neighbours(iatref,ishell)%transpose_in_shell(iatshell)
183 : 1631 : call tdep_build_phi4_3333(isym,Phi4_ref(:,:,:,:,ishell),Phi4_3333,Sym,itrans)
184 : 1631 : write(Invar%stdout,'(a,i4,a,i4)') ' For iatcell=',iatref,' ,with type=',mod(iatref-1,Invar%natom_unitcell)+1
185 : 1631 : write(Invar%stdout,'(a,i4,a,i4)') ' For jatom =',jatom ,' ,with type=',mod(jatom -1,Invar%natom_unitcell)+1
186 : 1631 : write(Invar%stdout,'(a,i4,a,i4)') ' For katom =',katom ,' ,with type=',mod(katom -1,Invar%natom_unitcell)+1
187 : 1631 : write(Invar%stdout,'(a,i4,a,i4)') ' For latom =',latom ,' ,with type=',mod(latom -1,Invar%natom_unitcell)+1
188 [ + + ]: 6524 : do ii=1,3
189 [ + + ]: 21203 : do jj=1,3
190 : : #if defined FC_NVHPC
191 : : if (itrans == -1) write(std_out, *)"NVHPC freezes here that is fixed by this print statement."
192 : : #endif
193 : :
194 : 14679 : write(Invar%stdout,'(a,i2,i2,a)') ' Phi4^{',ii,jj,'kl}='
195 [ + + ]: 63609 : do kk=1,3
196 [ + + ]: 44037 : if (abs(Phi4_3333(ii,jj,1,kk)).lt.5.d-7) then
197 : 7416 : tmp1=0.d0
198 : : else
199 : 36621 : tmp1=Phi4_3333(ii,jj,1,kk)
200 : : end if
201 [ + + ]: 44037 : if (abs(Phi4_3333(ii,jj,2,kk)).lt.5.d-7) then
202 : 7306 : tmp2=0.d0
203 : : else
204 : 36731 : tmp2=Phi4_3333(ii,jj,2,kk)
205 : : end if
206 [ + + ]: 44037 : if (abs(Phi4_3333(ii,jj,3,kk)).lt.5.d-7) then
207 : 7410 : tmp3=0.d0
208 : : else
209 : 36627 : tmp3=Phi4_3333(ii,jj,3,kk)
210 : : end if
211 : 58716 : write(Invar%stdout,'(2x,3(f9.6,1x))') tmp1,tmp2,tmp3
212 : : end do
213 : : end do
214 : : end do
215 : 1631 : write(Invar%stdout,'(a,3(f9.6,1x))') ' (i,j) vector components:', (distance(iatref,jatom,jj+1),jj=1,3)
216 : 1631 : write(Invar%stdout,'(a,3(f9.6,1x))') ' (j,k) vector components:', (distance(jatom ,katom,jj+1),jj=1,3)
217 : 1631 : write(Invar%stdout,'(a,3(f9.6,1x))') ' (j,k) vector components:', (distance(katom ,latom,jj+1),jj=1,3)
218 : 1631 : write(Invar%stdout,'(a,3(f9.6,1x))') ' (k,i) vector components:', (distance(latom,iatref,jj+1),jj=1,3)
219 : 1677 : write(Invar%stdout,*) ' '
220 : : end do !iatshell
221 : : end if !n_interactions
222 : : end do !ishell
223 [ - + ]: 8 : ABI_FREE(Phi4_3333)
224 : :
225 : 8 : end subroutine tdep_write_phi4
226 : :
227 : : !=====================================================================================================
228 : 245363 : subroutine tdep_build_phi4_3333(isym,Phi4_ref,Phi4_3333,Sym,itrans)
229 : :
230 : : type(Symmetries_type),intent(in) :: Sym
231 : : double precision, intent(in) :: Phi4_ref(3,3,3,3)
232 : : double precision, intent(out) :: Phi4_3333(3,3,3,3)
233 : : integer,intent(in) :: isym,itrans
234 : :
235 : : integer :: alpha,beta,gama,delta
236 : : integer :: ii,jj,kk,ll,ee,ff,gg,hh,mu,nu,xi,zeta
237 : : double precision :: Phi4_tmp(3,3,3,3)
238 : :
239 : :
240 : : ! Transform in the new basis wrt S_ref
241 : 245363 : Phi4_3333(:,:,:,:)=zero
242 [ + + ]: 981452 : do mu=1,3
243 [ + + ]: 3189719 : do alpha=1,3
244 [ + + ]: 9569157 : do nu=1,3
245 [ + + ]: 28707471 : do beta=1,3
246 [ + + ]: 86122413 : do xi=1,3
247 [ + + ]: 258367239 : do gama=1,3
248 [ + + ]: 775101717 : do zeta=1,3
249 [ + + ]: 2325305151 : do delta=1,3
250 : : #if defined FC_NVHPC
251 : : if (itrans == -1) write(std_out, *)"NVHPC freezes here that is fixed by this print statement."
252 : : #endif
253 : : Phi4_3333(mu,nu,xi,zeta)=Phi4_3333(mu,nu,xi,zeta)+&
254 : : & Sym%S_ref(mu,alpha,isym,1)*Sym%S_ref(nu ,beta ,isym,1)*&
255 : 2146435524 : & Sym%S_ref(xi,gama ,isym,1)*Sym%S_ref(zeta,delta,isym,1)*Phi4_ref(alpha,beta,gama,delta)
256 : : end do
257 : : end do
258 : : end do
259 : : end do
260 : : end do
261 : : end do
262 : : end do
263 : : end do
264 : :
265 : : ! Take into account the 6 allowed permutations
266 : 245363 : Phi4_tmp(:,:,:,:)=Phi4_3333(:,:,:,:)
267 [ - + ]: 245363 : if ((itrans.lt.1).or.(itrans.gt.24)) then
268 : 0 : ABI_BUG('This value of the symmetry index is not permitted')
269 : : end if
270 [ + + ]: 981452 : do ii=1,3
271 [ + + ]: 3189719 : do jj=1,3
272 [ + + ]: 9569157 : do kk=1,3
273 [ + + ]: 28707471 : do ll=1,3
274 : : #if defined FC_NVHPC
275 : : if (itrans == -1) write(std_out, *)"NVHPC freezes here that is fixed by this print statement."
276 : : #endif
277 : :
278 [ + + ]: 19874403 : if (itrans==1) then ; ee=ii ; ff=jj ; gg=kk ; hh=ll ; endif !\Phi4_ijkl
279 [ + + ]: 19874403 : if (itrans==2) then ; ee=ii ; ff=kk ; gg=jj ; hh=ll ; endif !\Phi4_ikjl
280 [ + + ]: 19874403 : if (itrans==3) then ; ee=jj ; ff=ii ; gg=kk ; hh=ll ; endif !\Phi4_jikl
281 [ + + ]: 19874403 : if (itrans==4) then ; ee=jj ; ff=kk ; gg=ii ; hh=ll ; endif !\Phi4_jkil
282 [ + + ]: 19874403 : if (itrans==5) then ; ee=kk ; ff=ii ; gg=jj ; hh=ll ; endif !\Phi4_kijl
283 [ + + ]: 19874403 : if (itrans==6) then ; ee=kk ; ff=jj ; gg=ii ; hh=ll ; endif !\Phi4_kjil
284 : :
285 [ + + ]: 19874403 : if (itrans==7 ) then ; ee=ii ; ff=jj ; gg=ll ; hh=kk ; endif !\Phi4_ijlk
286 [ + + ]: 19874403 : if (itrans==8 ) then ; ee=ii ; ff=kk ; gg=ll ; hh=jj ; endif !\Phi4_iklj
287 [ + + ]: 19874403 : if (itrans==9 ) then ; ee=jj ; ff=ii ; gg=ll ; hh=kk ; endif !\Phi4_jilk
288 [ + + ]: 19874403 : if (itrans==10) then ; ee=jj ; ff=kk ; gg=ll ; hh=ii ; endif !\Phi4_jkli
289 [ + + ]: 19874403 : if (itrans==11) then ; ee=kk ; ff=ii ; gg=ll ; hh=jj ; endif !\Phi4_kilj
290 [ + + ]: 19874403 : if (itrans==12) then ; ee=kk ; ff=jj ; gg=ll ; hh=ii ; endif !\Phi4_kjli
291 : :
292 [ + + ]: 19874403 : if (itrans==13) then ; ee=ii ; ff=ll ; gg=jj ; hh=kk ; endif !\Phi4_iljk
293 [ + + ]: 19874403 : if (itrans==14) then ; ee=ii ; ff=ll ; gg=kk ; hh=jj ; endif !\Phi4_ilkj
294 [ + + ]: 19874403 : if (itrans==15) then ; ee=jj ; ff=ll ; gg=ii ; hh=kk ; endif !\Phi4_jlik
295 [ + + ]: 19874403 : if (itrans==16) then ; ee=jj ; ff=ll ; gg=kk ; hh=ii ; endif !\Phi4_jlki
296 [ + + ]: 19874403 : if (itrans==17) then ; ee=kk ; ff=ll ; gg=ii ; hh=jj ; endif !\Phi4_klij
297 [ + + ]: 19874403 : if (itrans==18) then ; ee=kk ; ff=ll ; gg=jj ; hh=ii ; endif !\Phi4_klji
298 : :
299 [ + + ]: 19874403 : if (itrans==19) then ; ee=ll ; ff=ii ; gg=jj ; hh=kk ; endif !\Phi4_lijk
300 [ + + ]: 19874403 : if (itrans==20) then ; ee=ll ; ff=ii ; gg=kk ; hh=jj ; endif !\Phi4_likj
301 [ + + ]: 19874403 : if (itrans==21) then ; ee=ll ; ff=jj ; gg=ii ; hh=kk ; endif !\Phi4_ljik
302 [ + + ]: 19874403 : if (itrans==22) then ; ee=ll ; ff=jj ; gg=kk ; hh=ii ; endif !\Phi4_ljki
303 [ + + ]: 19874403 : if (itrans==23) then ; ee=ll ; ff=kk ; gg=ii ; hh=jj ; endif !\Phi4_lkij
304 [ + + ]: 19874403 : if (itrans==24) then ; ee=ll ; ff=kk ; gg=jj ; hh=ii ; endif !\Phi4_lkji
305 : :
306 : 26499204 : Phi4_3333(ee,ff,gg,hh)=Phi4_tmp(ii,jj,kk,ll)
307 : : end do
308 : : end do
309 : : end do
310 : : end do
311 : :
312 : 245363 : end subroutine tdep_build_phi4_3333
313 : :
314 : : !=====================================================================================================
315 : : end module m_tdep_phi4
|