Branch data Line data Source code
1 : : !!****m* ABINIT/m_xfpack
2 : : !! NAME
3 : : !! m_xfpack
4 : : !!
5 : : !! FUNCTION
6 : : !!
7 : : !! COPYRIGHT
8 : : !! Copyright (C) 1998-2026 ABINIT group (XG, MJV, DCA, GMR, JCC, SE)
9 : : !! This file is distributed under the terms of the
10 : : !! GNU General Public License, see ~abinit/COPYING
11 : : !! or http://www.gnu.org/copyleft/gpl.txt .
12 : : !!
13 : : !! SOURCE
14 : :
15 : : #if defined HAVE_CONFIG_H
16 : : #include "config.h"
17 : : #endif
18 : :
19 : : #include "abi_common.h"
20 : :
21 : : module m_xfpack
22 : :
23 : : use defs_basis
24 : : use m_errors
25 : : use m_abicore
26 : : use m_abimover
27 : :
28 : : use m_matrix, only : matr3inv
29 : : use m_geometry, only : mkradim, mkrdim, metric, strainsym
30 : : use m_results_gs , only : results_gs_type
31 : : use m_bfgs, only : hessupdt
32 : :
33 : : implicit none
34 : :
35 : : private
36 : : !!***
37 : :
38 : : public :: xfpack_vin2x
39 : : public :: xfpack_x2vin
40 : : public :: xfpack_f2vout
41 : : public :: xfh_recover_new
42 : : public :: xfh_update
43 : : !!***
44 : :
45 : : contains
46 : : !!***
47 : :
48 : : !!****f* ABINIT/xfpack_vin2x
49 : : !! NAME
50 : : !! xfpack_vin2x
51 : : !!
52 : : !! FUNCTION
53 : : !! Old option=2, transfer vin to xred, acell and rprim
54 : : !!
55 : : !! INPUTS
56 : : !! acell0(3)=reference length scales of primitive translations (bohr), needed for some values of optcell.
57 : : !! natom=number of atoms in cell
58 : : !! ndim=dimension of vin array
59 : : !! nsym=order of group.
60 : : !! rprimd0(3,3)=reference real space primitive translations,
61 : : !! needed for some values of optcell.
62 : : !! optcell=option for the optimisation of the unit cell. Described in abinit_help.
63 : : !! Depending on its value, different part of acell and rprim
64 : : !! are contained in vin.
65 : : !! symrel(3,3,nsym)=symmetry operators in terms of action on primitive translations
66 : : !! ucvol=unit cell volume (bohr^3), needed for some values of optcell.
67 : : !! ucvol0=reference unit cell volume (bohr^3), needed for some values of optcell.
68 : : !!
69 : : !! OUTPUT
70 : : !! (see side effects)
71 : : !!
72 : : !! SIDE EFFECTS
73 : : !! Input/Output variables
74 : : !! acell(3)=length scales of primitive translations (bohr)
75 : : !! rprim(3,3)=dimensionless real space primitive translations
76 : : !! vin(ndim)=vector that contains xred and some quantity derived
77 : : !! from acell and rprim, depending on the value of optcell.
78 : : !! xred(3,natom)=reduced dimensionless atomic coordinates
79 : : !!
80 : : !! SOURCE
81 : :
82 : 1009 : subroutine xfpack_vin2x(acell,acell0,natom,ndim,nsym,optcell,&
83 : 1009 : & rprim,rprimd0,symrel,ucvol,ucvol0,vin,xred)
84 : :
85 : : !Arguments ------------------------------------
86 : : !scalars
87 : : integer,intent(in) :: natom,ndim,nsym,optcell
88 : : real(dp),intent(in) :: ucvol0
89 : : real(dp),intent(out) :: ucvol
90 : : !arrays
91 : : integer,intent(in) :: symrel(3,3,nsym)
92 : : real(dp),intent(in) :: acell0(3),rprimd0(3,3)
93 : : real(dp),intent(inout) :: acell(3),rprim(3,3)
94 : : real(dp),intent(in) :: vin(ndim)
95 : : real(dp),intent(out) :: xred(3,natom)
96 : :
97 : : !Local variables-------------------------------
98 : : !scalars
99 : : integer :: ii,jj,kk
100 : : real(dp) :: scale
101 : : character(len=500) :: message
102 : : logical :: equal=.TRUE.
103 : : !arrays
104 : : real(dp) :: gmet(3,3),gprimd(3,3),rmet(3,3),rprimd(3,3)
105 : : real(dp) :: rprimd_symm(3,3),scaling(3,3)
106 : :
107 : : ! *************************************************************************
108 : :
109 : : !!DEBUG
110 : : !write(ab_out,*) ''
111 : : !write(ab_out,*) 'xfpack_vin2x'
112 : : !write(ab_out,*) 'natom=',natom
113 : : !write(ab_out,*) 'ndim=',ndim
114 : : !write(ab_out,*) 'nsym=',nsym
115 : : !write(ab_out,*) 'optcell=',optcell
116 : : !write(ab_out,*) 'ucvol=',ucvol
117 : : !write(ab_out,*) 'xred='
118 : : !do kk=1,natom
119 : : !write(ab_out,*) xred(:,kk)
120 : : !end do
121 : : !write(ab_out,*) 'VECTOR INPUT (vin) xfpack_vin2x INPUT'
122 : : !do ii=1,ndim,3
123 : : !if (ii+2<=ndim)then
124 : : !write(ab_out,*) ii,vin(ii:ii+2)
125 : : !else
126 : : !write(ab_out,*) ii,vin(ii:ndim)
127 : : !end if
128 : : !end do
129 : : !!DEBUG
130 : :
131 : :
132 : : !##########################################################
133 : : !### 1. Test for compatible ndim
134 : :
135 [ + + - + ]: 1009 : if(optcell==0 .and. ndim/=3*natom)then
136 : : write(message,'(a,a,a,i4,a,i4,a)' )&
137 : 0 : & ' When optcell=0, ndim MUST be equal to 3*natom,',ch10,&
138 : 0 : & ' while ndim=',ndim,' and 3*natom=',3*natom,'.'
139 : 0 : ABI_BUG(messagE)
140 : : end if
141 : :
142 [ + + - + ]: 1009 : if( (optcell==1) .and. ndim/=3*natom+1)then
143 : : write(message,'(a,a,a,i4,a,i4,a)' )&
144 : 0 : & ' When optcell=1 ndim MUST be equal to 3*natom+1,',ch10,&
145 : 0 : & ' while ndim=',ndim,' and 3*natom+1=',3*natom+1,'.'
146 : 0 : ABI_BUG(message)
147 : : end if
148 : :
149 [ + + - + ]: 1009 : if( (optcell==2 .or. optcell==3) .and. ndim/=3*natom+6) then
150 : : write(message,'(a,a,a,i4,a,i4,a)' )&
151 : 0 : & ' When optcell=2 or 3, ndim MUST be equal to 3*natom+6,',ch10,&
152 : 0 : & ' while ndim=',ndim,' and 3*natom+6=',3*natom+6,'.'
153 : 0 : ABI_BUG(message)
154 : : end if
155 : :
156 [ + + - + ]: 1009 : if( optcell>=4 .and. ndim/=3*natom+3)then
157 : : write(message,'(a,a,a,i4,a,i4,a)' )&
158 : 0 : & ' When optcell=4,5,6,7,8 or 9, ndim MUST be equal to 3*natom+3,',ch10,&
159 : 0 : & ' while ndim=',ndim,' and 3*natom+3=',3*natom+3,'.'
160 : 0 : ABI_BUG(message)
161 : : end if
162 : :
163 : : !##########################################################
164 : : !### 3. option=2, transfer vin to xred, acell and rprim
165 : :
166 : : !Get xred, and eventually acell and rprim from vin
167 [ + + ]: 3027 : xred(:,:)=reshape( vin(1:3*natom), (/3,natom/) )
168 : :
169 [ + + ]: 1009 : if(optcell==1)then
170 : :
171 : : ! acell(:)=acell0(:)*vin(3*natom+1)/(ucvol0**third)
172 [ + + ]: 632 : acell(:)=acell0(:)*vin(3*natom+1)
173 : :
174 [ + + ]: 851 : else if (optcell>=2)then
175 : :
176 : 160 : scaling(:,:)=0.0_dp
177 [ + + - + : 160 : scaling(1,1)=1.0_dp ; scaling(2,2)=1.0_dp ; scaling(3,3)=1.0_dp
+ - + - ]
178 : :
179 : : if(optcell==2 .or. optcell==3)then
180 : 129 : scaling(1,1)=vin(3*natom+1)
181 : 129 : scaling(2,2)=vin(3*natom+2)
182 : 129 : scaling(3,3)=vin(3*natom+3)
183 : 129 : scaling(2,3)=vin(3*natom+4) ; scaling(3,2)=vin(3*natom+4)
184 : 129 : scaling(1,3)=vin(3*natom+5) ; scaling(3,1)=vin(3*natom+5)
185 : 129 : scaling(1,2)=vin(3*natom+6) ; scaling(2,1)=vin(3*natom+6)
186 : : else if(optcell==4)then
187 : 9 : scaling(1,1)=vin(3*natom+1)
188 [ - + ]: 9 : if (abs(scaling(1,1) - 1.0_dp) <1.E-14) scaling(1,1)=1.0_dp
189 : 9 : scaling(3,1)=vin(3*natom+2)
190 [ + - ]: 9 : if (abs(scaling(3,1)) <1.E-14) scaling(3,1)=0.0_dp
191 : 9 : scaling(2,1)=vin(3*natom+3)
192 [ + - ]: 9 : if (abs(scaling(2,1)) <1.E-14) scaling(2,1)=0.0_dp
193 : : else if(optcell==5)then
194 : 0 : scaling(2,2)=vin(3*natom+1)
195 [ # # ]: 0 : if (abs(scaling(2,2) - 1.0_dp) <1.E-14) scaling(2,2)=1.0_dp
196 : 0 : scaling(3,2)=vin(3*natom+2)
197 [ # # ]: 0 : if (abs(scaling(3,2)) <1.E-14) scaling(3,2)=0.0_dp
198 : 0 : scaling(1,2)=vin(3*natom+3)
199 [ # # ]: 0 : if (abs(scaling(1,2)) <1.E-14) scaling(1,2)=0.0_dp
200 : : else if(optcell==6)then
201 : 5 : scaling(3,3)=vin(3*natom+1)
202 [ - + ]: 5 : if (abs(scaling(3,3) - 1.0_dp) <1.E-14) scaling(3,3)=1.0_dp
203 : 5 : scaling(2,3)=vin(3*natom+2)
204 [ + + ]: 5 : if (abs(scaling(2,3)) <1.E-14) scaling(2,3)=0.0_dp
205 : 5 : scaling(1,3)=vin(3*natom+3)
206 [ + + ]: 5 : if (abs(scaling(1,3)) <1.E-14) scaling(1,3)=0.0_dp
207 : : else if(optcell==7)then
208 : 13 : scaling(2,2)=vin(3*natom+2) ; scaling(3,3)=vin(3*natom+3)
209 : 13 : scaling(2,3)=vin(3*natom+1) ; scaling(3,2)=vin(3*natom+1)
210 : : else if(optcell==8)then
211 : 0 : scaling(1,1)=vin(3*natom+1) ; scaling(3,3)=vin(3*natom+3)
212 : 0 : scaling(1,3)=vin(3*natom+2) ; scaling(3,1)=vin(3*natom+2)
213 : : else if(optcell==9)then
214 : 4 : scaling(1,1)=vin(3*natom+1) ; scaling(2,2)=vin(3*natom+2)
215 : 4 : scaling(1,2)=vin(3*natom+3) ; scaling(2,1)=vin(3*natom+3)
216 : : end if
217 [ + + ]: 160 : if(optcell<=3 .or. optcell>=7)then
218 [ + + ]: 584 : do ii=1,3
219 [ + + ]: 1898 : do jj=1,3
220 : 1314 : rprimd(ii,jj)=0.0_dp
221 [ + + ]: 5694 : do kk=1,3
222 : 5256 : rprimd(ii,jj)=rprimd(ii,jj)+scaling(ii,kk)*rprimd0(kk,jj)
223 : : end do
224 : : end do
225 : : end do
226 : : ! for optcell=4,5,6, implementing search for all 3 components of the vector to be relaxed according to Eq.10 of J. Chem. Phys.
227 : : ! 136, 074103 (2012), i.e. search direction given by rprimd0 * stress
228 [ + + ]: 14 : else if(optcell==4)then
229 [ + + ]: 36 : rprimd(:,2) = rprimd0(:,2)
230 [ + + ]: 36 : rprimd(:,3) = rprimd0(:,3)
231 [ + + ]: 36 : rprimd(:,1) = 0.0_dp
232 [ + + ]: 36 : do ii=1,3
233 [ + + ]: 117 : do kk=1,3
234 : 108 : rprimd(ii,1) = rprimd(ii,1) + scaling(kk,1)*rprimd0(ii,kk)
235 : : end do
236 : : end do
237 [ - + ]: 5 : else if(optcell==5)then
238 [ # # ]: 0 : rprimd(:,1) = rprimd0(:,1)
239 [ # # ]: 0 : rprimd(:,3) = rprimd0(:,3)
240 [ # # ]: 0 : rprimd(:,2) = 0.0_dp
241 [ # # ]: 0 : do ii=1,3
242 [ # # ]: 0 : do kk=1,3
243 : 0 : rprimd(ii,2) = rprimd(ii,2) + scaling(kk,2)*rprimd0(ii,kk)
244 : : end do
245 : : end do
246 : : else if(optcell==6)then
247 [ + + ]: 20 : rprimd(:,1) = rprimd0(:,1)
248 [ + + ]: 20 : rprimd(:,2) = rprimd0(:,2)
249 [ + + ]: 20 : rprimd(:,3) = 0.0_dp
250 [ + + ]: 20 : do ii=1,3
251 [ + + ]: 65 : do kk=1,3
252 : 60 : rprimd(ii,3) = rprimd(ii,3) + scaling(kk,3)*rprimd0(ii,kk)
253 : : end do
254 : : end do
255 : : end if
256 : :
257 : : ! Rescale if the volume must be preserved
258 [ + + ]: 160 : if(optcell==3)then
259 : 11 : call metric(gmet,gprimd,-1,rmet,rprimd,ucvol)
260 : 11 : scale=(ucvol0/ucvol)**third
261 [ + + + + ]: 143 : rprimd(:,:)=scale*rprimd(:,:)
262 : : end if
263 : 160 : call strainsym(nsym,rprimd0,rprimd,rprimd_symm,symrel)
264 [ + + ]: 640 : do jj=1,3
265 [ + + ]: 2080 : do ii=1,3
266 : : ! write(ab_out,*) 'DIFF',ii,jj,abs(rprimd0(ii,jj)-rprimd_symm(ii,jj))
267 [ + + ]: 1440 : if (abs(rprimd0(ii,jj)-rprimd_symm(ii,jj))>1.E-14)&
268 : 1335 : & equal=.FALSE.
269 : : end do
270 : : end do
271 : :
272 [ - + ]: 160 : if (equal)then
273 : 0 : acell(:)=acell0(:)
274 : : rprimd(:,:)=rprimd0(:,:)
275 : : else
276 : : ! Use a representation based on normalised rprim vectors
277 : 160 : call mkradim(acell,rprim,rprimd_symm)
278 : : end if
279 : :
280 : : end if
281 : :
282 : 1009 : end subroutine xfpack_vin2x
283 : : !!***
284 : :
285 : : !!****f* ABINIT/xfpack_x2vin
286 : : !! NAME
287 : : !! xfpack_x2vin
288 : : !!
289 : : !! FUNCTION
290 : : !! Old option=1, transfer xred, acell, and rprim to vin
291 : : !!
292 : : !! INPUTS
293 : : !! acell0(3)=reference length scales of primitive translations (bohr), needed for some values of optcell.
294 : : !! natom=number of atoms in cell
295 : : !! ndim=dimension of vin arrays
296 : : !! nsym=order of group.
297 : : !! rprimd0(3,3)=reference real space primitive translations,
298 : : !! needed for some values of optcell.
299 : : !! optcell=option for the optimisation of the unit cell. Described in abinit_help.
300 : : !! Depending on its value, different part of acell and rprim
301 : : !! are contained in vin.
302 : : !! symrel(3,3,nsym)=symmetry operators in terms of action on primitive translations
303 : : !! ucvol=unit cell volume (bohr^3), needed for some values of optcell.
304 : : !! ucvol0=reference unit cell volume (bohr^3), needed for some values of optcell.
305 : : !!
306 : : !! OUTPUT
307 : : !! (see side effects)
308 : : !!
309 : : !! SIDE EFFECTS
310 : : !! Input/Output variables
311 : : !! acell(3)=length scales of primitive translations (bohr)
312 : : !! rprim(3,3)=dimensionless real space primitive translations
313 : : !! vin(ndim)=vector that contains xred and some quantity derived
314 : : !! from acell and rprim, depending on the value of optcell.
315 : : !! xred(3,natom)=reduced dimensionless atomic coordinates
316 : : !!
317 : : !! SOURCE
318 : :
319 : 1027 : subroutine xfpack_x2vin(acell,natom,ndim,nsym,optcell,&
320 : 1027 : & rprim,rprimd0,symrel,ucvol,ucvol0,vin,xred)
321 : :
322 : : !Arguments ------------------------------------
323 : : !scalars
324 : : integer,intent(in) :: natom,ndim,nsym,optcell
325 : : real(dp),intent(in) :: ucvol0
326 : : real(dp),intent(inout) :: ucvol !vz_i
327 : : !arrays
328 : : integer,intent(in) :: symrel(3,3,nsym)
329 : : real(dp),intent(in) :: rprimd0(3,3)
330 : : real(dp),intent(in) :: acell(3),rprim(3,3)
331 : : real(dp),intent(in) :: xred(3,natom)
332 : : real(dp),intent(out) :: vin(ndim)
333 : :
334 : : !Local variables-------------------------------
335 : : !scalars
336 : : integer :: ii,jj,kk
337 : : real(dp) :: scale
338 : : character(len=500) :: message
339 : : !arrays
340 : : real(dp) :: gmet(3,3),gprimd(3,3),gprimd0(3,3),rmet(3,3),rprimd(3,3)
341 : : real(dp) :: rprimd_symm(3,3),scaling(3,3)
342 : :
343 : : ! *************************************************************************
344 : :
345 : : !!DEBUG
346 : : !write(ab_out,*) ''
347 : : !write(ab_out,*) 'xfpack_x2vin'
348 : : !write(ab_out,*) 'natom=',natom
349 : : !write(ab_out,*) 'ndim=',ndim
350 : : !write(ab_out,*) 'nsym=',nsym
351 : : !write(ab_out,*) 'optcell=',optcell
352 : : !write(ab_out,*) 'ucvol=',ucvol
353 : : !write(ab_out,*) 'xred='
354 : : !do kk=1,natom
355 : : !write(ab_out,*) xred(:,kk)
356 : : !end do
357 : : !write(ab_out,*) 'VECTOR INPUT (vin) xfpack_x2vin INPUT'
358 : : !do ii=1,ndim,3
359 : : !if (ii+2<=ndim)then
360 : : !write(ab_out,*) ii,vin(ii:ii+2)
361 : : !else
362 : : !write(ab_out,*) ii,vin(ii:ndim)
363 : : !end if
364 : : !end do
365 : : !!DEBUG
366 : :
367 : :
368 : : !##########################################################
369 : : !### 1. Test for compatible ndim
370 : :
371 [ + + - + ]: 1027 : if(optcell==0 .and. ndim/=3*natom)then
372 : : write(message,'(a,a,a,i4,a,i4,a)' )&
373 : 0 : & ' When optcell=0, ndim MUST be equal to 3*natom,',ch10,&
374 : 0 : & ' while ndim=',ndim,' and 3*natom=',3*natom,'.'
375 : 0 : ABI_BUG(message)
376 : : end if
377 : :
378 [ + + - + ]: 1027 : if( optcell==1 .and. ndim/=3*natom+1)then
379 : : write(message,'(a,a,a,i4,a,i4,a)' )&
380 : 0 : & ' When optcell=1, ndim MUST be equal to 3*natom+1,',ch10,&
381 : 0 : & ' while ndim=',ndim,' and 3*natom+1=',3*natom+1,'.'
382 : 0 : ABI_BUG(message)
383 : : end if
384 : :
385 : : if( (optcell==2 .or. optcell==3) &
386 [ + + - + ]: 1027 : & .and. ndim/=3*natom+6)then
387 : : write(message,'(a,a,a,i4,a,i4,a)' )&
388 : 0 : & ' When optcell=2,3,4,5,6, ndim MUST be equal to 3*natom+6,',ch10,&
389 : 0 : & ' while ndim=',ndim,' and 3*natom+6=',3*natom+6,'.'
390 : 0 : ABI_BUG(message)
391 : : end if
392 : :
393 [ + + - + ]: 1027 : if( optcell>=4 .and. ndim/=3*natom+3)then
394 : : write(message,'(a,a,a,i4,a,i4,a)' )&
395 : 0 : & ' When optcell=4,5,6,7,8 or 9, ndim MUST be equal to 3*natom+3,',ch10,&
396 : 0 : & ' while ndim=',ndim,' and 3*natom+3=',3*natom+3,'.'
397 : 0 : ABI_BUG(message)
398 : : end if
399 : :
400 : : !##########################################################
401 : : !### 2. option=1, transfer xred, acell, and rprim to vin
402 : :
403 : : !Get vin from xred, acell, and rprim
404 [ + + ]: 2054 : vin(1:3*natom)= reshape(xred(:,:), (/3*natom/) )
405 : :
406 [ + + ]: 1027 : if(optcell/=0)then
407 : 318 : call mkrdim(acell,rprim,rprimd)
408 : 318 : call strainsym(nsym,rprimd0,rprimd,rprimd_symm,symrel)
409 : 318 : call metric(gmet,gprimd,-1,rmet,rprimd_symm,ucvol)
410 : :
411 [ + + ]: 318 : if(optcell==1)then
412 : :
413 : : ! vin(3*natom+1)=ucvol**third
414 : 158 : vin(3*natom+1)=(ucvol/ucvol0)**third
415 : :
416 [ + - ]: 160 : else if(optcell>=2)then
417 : :
418 : : ! Generates gprimd0
419 : 160 : call matr3inv(rprimd0,gprimd0)
420 [ + + ]: 160 : if (optcell==2 .or. optcell==3 .or. optcell>=7)then
421 [ + + ]: 584 : do ii=1,3
422 [ + + ]: 1898 : do jj=1,3
423 : 1314 : scaling(ii,jj)=0.0_dp
424 [ + + ]: 5694 : do kk=1,3
425 : 5256 : scaling(ii,jj)=scaling(ii,jj)+rprimd_symm(ii,kk)*gprimd0(jj,kk)
426 : : end do
427 : : end do
428 : : end do
429 : : ! Rescale if the volume must be preserved
430 [ + + ]: 146 : if(optcell==3)then
431 : 11 : scale=(ucvol0/ucvol)**third
432 [ + + + + ]: 143 : scaling(:,:)=scale*scaling(:,:)
433 : : end if
434 [ + + ]: 146 : if(optcell==2 .or. optcell==3)then
435 : 129 : vin(3*natom+1)=scaling(1,1) ; vin(3*natom+4)=(scaling(2,3)+scaling(3,2))*0.5_dp
436 : 129 : vin(3*natom+2)=scaling(2,2) ; vin(3*natom+5)=(scaling(1,3)+scaling(3,1))*0.5_dp
437 : 129 : vin(3*natom+3)=scaling(3,3) ; vin(3*natom+6)=(scaling(1,2)+scaling(2,1))*0.5_dp
438 [ + - ]: 17 : else if(optcell>=7)then
439 : 17 : vin(3*natom+1)=scaling(1,1)
440 : 17 : vin(3*natom+2)=scaling(2,2)
441 : 17 : vin(3*natom+3)=scaling(3,3)
442 [ + + ]: 17 : if(optcell==7)vin(3*natom+1)=(scaling(2,3)+scaling(3,2))*0.5_dp
443 [ - + ]: 17 : if(optcell==8)vin(3*natom+2)=(scaling(1,3)+scaling(3,1))*0.5_dp
444 [ + + ]: 17 : if(optcell==9)vin(3*natom+3)=(scaling(1,2)+scaling(2,1))*0.5_dp
445 : : end if
446 : : end if
447 : :
448 [ + + ]: 160 : if (optcell==4)then
449 : 9 : scaling(:,:) = 0.0_dp
450 [ + + ]: 36 : do ii=1,3
451 [ + + ]: 117 : do kk=1,3
452 : 108 : scaling(ii,1) = scaling(ii,1) + gprimd0(kk,ii)*rprimd_symm(kk,1)
453 : : end do
454 : : end do
455 : 9 : vin(3*natom+1) = scaling(1,1)
456 : 9 : vin(3*natom+2) = scaling(3,1)
457 : 9 : vin(3*natom+3) = scaling(2,1)
458 [ - + ]: 151 : else if (optcell==5)then
459 : 0 : scaling(:,:) = 0.0_dp
460 [ # # ]: 0 : do ii=1,3
461 [ # # ]: 0 : do kk=1,3
462 : 0 : scaling(ii,2) = scaling(ii,2) + gprimd0(kk,ii)*rprimd_symm(kk,2)
463 : : end do
464 : : end do
465 : 0 : vin(3*natom+1) = scaling(2,2)
466 : 0 : vin(3*natom+2) = scaling(3,2)
467 : 0 : vin(3*natom+3) = scaling(1,2)
468 [ + + ]: 151 : else if (optcell==6)then
469 : 5 : scaling(:,:) = 0.0_dp
470 [ + + ]: 20 : do ii=1,3
471 [ + + ]: 65 : do kk=1,3
472 : 60 : scaling(ii,3) = scaling(ii,3) + gprimd0(kk,ii)*rprimd_symm(kk,3)
473 : : end do
474 : : end do
475 : 5 : vin(3*natom+1) = scaling(3,3)
476 : 5 : vin(3*natom+2) = scaling(2,3)
477 : 5 : vin(3*natom+3) = scaling(1,3)
478 : : end if
479 : :
480 : : end if
481 : :
482 : : end if
483 : :
484 : 1027 : end subroutine xfpack_x2vin
485 : : !!***
486 : :
487 : : !!****f* ABINIT/xfpack_f2vout
488 : : !! NAME
489 : : !! xfpack_f2vout
490 : : !!
491 : : !! FUNCTION
492 : : !! Old option=3, transfer gred and strten to vout
493 : : !!
494 : : !! INPUTS
495 : : !! natom=number of atoms in cell
496 : : !! ndim=dimension of vout arrays
497 : : !! optcell=option for the optimisation of the unit cell. Described in abinit_help.
498 : : !! Depending on its value, different part of strten
499 : : !! are contained in vout.
500 : : !! strtarget(6)=target stresses ; they will be subtracted from strten when vout
501 : : !! is computed.
502 : : !! ucvol=unit cell volume (bohr^3), needed for some values of optcell.
503 : : !!
504 : : !! OUTPUT
505 : : !! (see side effects)
506 : : !!
507 : : !! SIDE EFFECTS
508 : : !! Input/Output variables
509 : : !! gred(3,natom)=grads of Etot wrt reduced coordinates (hartree)
510 : : !! strten(6)=components of the stress tensor (hartree/bohr^3)
511 : : !! vout(ndim)=vector that contains gred and some quantity derived from
512 : : !! strten, depending on the value of optcell, and taking care ot strtarget
513 : : !!
514 : : !! SOURCE
515 : :
516 : 1009 : subroutine xfpack_f2vout(gred,natom,ndim,optcell,strtarget,strten,ucvol,vout)
517 : :
518 : : !Arguments ------------------------------------
519 : : !scalars
520 : : integer,intent(in) :: natom,ndim,optcell
521 : : real(dp),intent(in) :: ucvol
522 : : !arrays
523 : : real(dp),intent(in) :: strtarget(6)
524 : : real(dp),intent(in) :: gred(3,natom),strten(6)
525 : : real(dp),intent(out) :: vout(ndim)
526 : :
527 : : !Local variables-------------------------------
528 : : !scalars
529 : : real(dp) :: strdiag
530 : : character(len=500) :: message
531 : : !arrays
532 : : real(dp) :: dstr(6)
533 : :
534 : : ! *************************************************************************
535 : :
536 : : !!DEBUG
537 : : !write(ab_out,*) ''
538 : : !write(ab_out,*) 'xfpack_f2vout'
539 : : !write(ab_out,*) 'natom=',natom
540 : : !write(ab_out,*) 'ndim=',ndim
541 : : !write(ab_out,*) 'optcell=',optcell
542 : : !write(ab_out,*) 'ucvol=',ucvol
543 : : !!DEBUG
544 : :
545 : :
546 : : !##########################################################
547 : : !### 1. Test for compatible ndim
548 : :
549 [ + + - + ]: 1009 : if(optcell==0 .and. ndim/=3*natom)then
550 : : write(message,'(a,a,a,i4,a,i4,a)' )&
551 : 0 : & ' When optcell=0, ndim MUST be equal to 3*natom,',ch10,&
552 : 0 : & ' while ndim=',ndim,' and 3*natom=',3*natom,'.'
553 : 0 : ABI_BUG(message)
554 : : end if
555 : :
556 [ + + - + ]: 1009 : if( optcell==1 .and. ndim/=3*natom+1)then
557 : : write(message,'(a,a,a,i4,a,i4,a)' )&
558 : 0 : & ' When optcell=1, ndim MUST be equal to 3*natom+1,',ch10,&
559 : 0 : & ' while ndim=',ndim,' and 3*natom+1=',3*natom+1,'.'
560 : 0 : ABI_BUG(message)
561 : : end if
562 : :
563 : : if( (optcell==2 .or. optcell==3) &
564 [ + + - + ]: 1009 : & .and. ndim/=3*natom+6)then
565 : : write(message,'(a,a,a,i4,a,i4,a)' )&
566 : 0 : & ' When optcell=2 or 3, ndim MUST be equal to 3*natom+6,',ch10,&
567 : 0 : & ' while ndim=',ndim,' and 3*natom+6=',3*natom+6,'.'
568 : 0 : ABI_BUG(message)
569 : : end if
570 : :
571 [ + + - + ]: 1009 : if( optcell>=4 .and. ndim/=3*natom+3)then
572 : : write(message,'(a,a,a,i4,a,i4,a)' )&
573 : 0 : & ' When optcell=4,5,6,7,8 or 9, ndim MUST be equal to 3*natom+3,',ch10,&
574 : 0 : & ' while ndim=',ndim,' and 3*natom+3=',3*natom+3,'.'
575 : 0 : ABI_BUG(message)
576 : : end if
577 : : !
578 : : !Get vout from gred and strten
579 : : !
580 [ + + ]: 2018 : vout(1:3*natom)= reshape(gred(:,:), (/3*natom/) )
581 [ + + ]: 7063 : dstr(:)=strten(:)-strtarget(:)
582 : :
583 [ + + ]: 1009 : if(optcell==1)then
584 : :
585 : 158 : vout(3*natom+1)=( dstr(1)+dstr(2)+dstr(3))*ucvol
586 : :
587 [ + + ]: 851 : else if(optcell>=2)then
588 : : ! Eventually take away the trace
589 : 160 : strdiag=0.0_dp
590 [ + + ]: 160 : if(optcell==3) strdiag=(dstr(1)+dstr(2)+dstr(3))/3.0_dp
591 : : if(optcell==2 .or. optcell==3)then
592 [ + + ]: 516 : vout(3*natom+1:3*natom+3)=(dstr(1:3)-strdiag)*ucvol
593 : : ! For non-diagonal derivatives, must take into account
594 : : ! that eps(i,j) AND eps(j,i) are varied at the same time. Thus, derivative
595 : : ! is twice larger
596 [ + + ]: 516 : vout(3*natom+4:3*natom+6)=dstr(4:6)*ucvol*2.0_dp
597 : : else if(optcell==7 .or. optcell==8 .or. optcell==9)then
598 : : ! Similar to case optcell==2 or optcell==3, but in 2 dimensions.
599 [ + + ]: 68 : vout(3*natom+1:3*natom+3)=dstr(1:3)*ucvol
600 : 17 : vout(3*natom+optcell-6) =dstr(optcell-3)*ucvol*2.0_dp
601 : : else if (optcell==4)then
602 : 9 : vout(3*natom+1) = dstr(1)*ucvol
603 : 9 : vout(3*natom+2) = dstr(5)*ucvol
604 : 9 : vout(3*natom+3) = dstr(6)*ucvol
605 : : else if (optcell==5)then
606 : 0 : vout(3*natom+1) = dstr(2)*ucvol
607 : 0 : vout(3*natom+2) = dstr(4)*ucvol
608 : 0 : vout(3*natom+3) = dstr(6)*ucvol
609 : : else if (optcell==6)then
610 : 5 : vout(3*natom+1) = dstr(3)*ucvol
611 : 5 : vout(3*natom+2) = dstr(4)*ucvol
612 : 5 : vout(3*natom+3) = dstr(5)*ucvol
613 : : end if
614 : :
615 : : end if
616 : :
617 : 1009 : end subroutine xfpack_f2vout
618 : : !!***
619 : :
620 : :
621 : : !!****f* ABINIT/xfh_recover_new
622 : : !! NAME
623 : : !! xfh_recover_new
624 : : !!
625 : : !! FUNCTION
626 : : !! Update the contents of the history xfhist taking values
627 : : !! from xred, acell, rprim, gred_corrected and strten
628 : : !!
629 : : !! INPUTS
630 : : !!
631 : : !! OUTPUT
632 : : !!
633 : : !! SOURCE
634 : :
635 : :
636 : 7 : subroutine xfh_recover_new(ab_xfh,ab_mover,acell,cycl_main,gred,&
637 [ - + - + ]: 7 : & hessin,ndim,rprim,rprimd0,strten,ucvol,ucvol0,vin,vin_prev,vout,&
638 [ - + - + : 14 : & vout_prev,xred)
- + ]
639 : :
640 : : !Arguments ------------------------------------
641 : : !scalars
642 : :
643 : : integer,intent(in) :: ndim
644 : : integer,intent(out) :: cycl_main
645 : : real(dp),intent(inout) :: ucvol,ucvol0
646 : : type(ab_xfh_type),intent(inout) :: ab_xfh
647 : : type(abimover),intent(in) :: ab_mover
648 : :
649 : :
650 : : !arrays
651 : : real(dp),intent(inout) :: acell(3)
652 : : real(dp),intent(inout) :: hessin(:,:)
653 : : real(dp),intent(inout) :: xred(3,ab_mover%natom)
654 : : real(dp),intent(inout) :: rprim(3,3)
655 : : real(dp),intent(inout) :: rprimd0(3,3)
656 : : real(dp),intent(inout) :: gred(3,ab_mover%natom)
657 : : real(dp),intent(inout) :: strten(6)
658 : : real(dp),intent(inout) :: vin(:)
659 : : real(dp),intent(inout) :: vin_prev(:)
660 : : real(dp),intent(inout) :: vout(:)
661 : : real(dp),intent(inout) :: vout_prev(:)
662 : :
663 : : !Local variables-------------------------------
664 : : !scalars
665 : : integer :: ixfh ! kk,jj
666 : :
667 : : !*********************************************************************
668 : :
669 [ - + ]: 7 : if(ab_xfh%nxfh/=0)then
670 : : ! Loop over previous time steps
671 [ # # ]: 0 : do ixfh=1,ab_xfh%nxfh
672 : :
673 : : ! For that time step, get new (x,f) from xfhist
674 [ # # # # ]: 0 : xred(:,:) =ab_xfh%xfhist(:,1:ab_mover%natom ,1,ixfh)
675 [ # # # # ]: 0 : rprim(1:3,1:3)=ab_xfh%xfhist(:,ab_mover%natom+2:ab_mover%natom+4,1,ixfh)
676 [ # # ]: 0 : acell(:) =ab_xfh%xfhist(:,ab_mover%natom+1,1,ixfh)
677 [ # # # # ]: 0 : gred(:,:) =ab_xfh%xfhist(:,1:ab_mover%natom,2,ixfh)
678 : : ! This use of results_gs is unusual
679 [ # # ]: 0 : strten(1:3) =ab_xfh%xfhist(:,ab_mover%natom+2,2,ixfh)
680 [ # # ]: 0 : strten(4:6) =ab_xfh%xfhist(:,ab_mover%natom+3,2,ixfh)
681 : :
682 : : ! !DEBUG
683 : : ! write (ab_out,*) '---READED FROM XFHIST---'
684 : :
685 : : ! write (ab_out,*) 'XRED'
686 : : ! do kk=1,ab_mover%natom
687 : : ! write (ab_out,*) xred(:,kk)
688 : : ! end do
689 : : ! write (ab_out,*) 'FRED'
690 : : ! do kk=1,ab_mover%natom
691 : : ! write (ab_out,*) gred(:,kk)
692 : : ! end do
693 : : ! write(ab_out,*) 'RPRIM'
694 : : ! do kk=1,3
695 : : ! write(ab_out,*) rprim(:,kk)
696 : : ! end do
697 : : ! write(ab_out,*) 'ACELL'
698 : : ! write(ab_out,*) acell(:)
699 : : ! !DEBUG
700 : :
701 : : ! Transfer it in vin, vout
702 : : call xfpack_x2vin(acell,ab_mover%natom,&
703 : : & ndim,ab_mover%nsym,ab_mover%optcell,rprim,rprimd0,&
704 [ # # # # : 0 : & ab_mover%symrel,ucvol,ucvol0,vin,xred)
# # # # #
# # # # #
# # # # #
# ]
705 : : call xfpack_f2vout(gred,ab_mover%natom,&
706 : : & ndim,ab_mover%optcell,ab_mover%strtarget,strten,&
707 [ # # # # : 0 : & ucvol,vout)
# # # # #
# # # # #
# # ]
708 : : ! Get old time step, if any, and update inverse hessian
709 [ # # ]: 0 : if(ixfh/=1)then
710 [ # # # # ]: 0 : xred(:,:) =ab_xfh%xfhist(:,1:ab_mover%natom,1,ixfh-1)
711 : : rprim(1:3,1:3)=&
712 [ # # # # ]: 0 : & ab_xfh%xfhist(:,ab_mover%natom+2:ab_mover%natom+4,1,ixfh-1)
713 [ # # ]: 0 : acell(:)=ab_xfh%xfhist(:,ab_mover%natom+1,1,ixfh-1)
714 [ # # # # ]: 0 : gred(:,:)=ab_xfh%xfhist(:,1:ab_mover%natom,2,ixfh-1)
715 : : ! This use of results_gs is unusual
716 [ # # ]: 0 : strten(1:3)=ab_xfh%xfhist(:,ab_mover%natom+2,2,ixfh-1)
717 [ # # ]: 0 : strten(4:6)=ab_xfh%xfhist(:,ab_mover%natom+3,2,ixfh-1)
718 : : ! Tranfer it in vin_prev, vout_prev
719 : : call xfpack_x2vin(acell,ab_mover%natom,&
720 : : & ndim,ab_mover%nsym,ab_mover%optcell,rprim,rprimd0,&
721 [ # # # # : 0 : & ab_mover%symrel,ucvol,ucvol0,vin_prev,xred)
# # # # #
# # # # #
# # # # #
# ]
722 : : call xfpack_f2vout(gred,ab_mover%natom,&
723 : : & ndim,ab_mover%optcell,ab_mover%strtarget,strten,&
724 [ # # # # : 0 : & ucvol,vout_prev)
# # # # #
# # # # #
# # ]
725 : :
726 : : ! write(ab_out,*) 'Hessian matrix before update',ndim,'x',ndim
727 : : ! write(ab_out,*) 'ixfh=',ixfh
728 : : ! do kk=1,ndim
729 : : ! do jj=1,ndim,3
730 : : ! if (jj+2<=ndim)then
731 : : ! write(ab_out,*) jj,hessin(jj:jj+2,kk)
732 : : ! else
733 : : ! write(ab_out,*) jj,hessin(jj:ndim,kk)
734 : : ! end if
735 : : ! end do
736 : : ! end do
737 : :
738 : : call hessupdt(hessin,ab_mover%iatfix,ab_mover%natom,ndim,&
739 [ # # # # : 0 : & vin,vin_prev,vout,vout_prev)
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # ]
740 : :
741 : : ! !DEBUG
742 : : ! write(ab_out,*) 'Hessian matrix after update',ndim,'x',ndim
743 : : ! do kk=1,ndim
744 : : ! do jj=1,ndim,3
745 : : ! if (jj+2<=ndim)then
746 : : ! write(ab_out,*) jj,hessin(jj:jj+2,kk)
747 : : ! else
748 : : ! write(ab_out,*) jj,hessin(jj:ndim,kk)
749 : : ! end if
750 : : ! end do
751 : : ! end do
752 : : ! !DEBUG
753 : :
754 : : end if !if(ab_xfh%nxfh/=0)
755 : : end do ! End loop over previous time steps
756 : :
757 : : ! The hessian has been generated,
758 : : ! as well as the latest vin and vout
759 : : ! so will cycle the main loop
760 : 0 : cycl_main=1
761 : : end if
762 : :
763 : 7 : end subroutine xfh_recover_new
764 : : !!***
765 : :
766 : : !!****f* ABINIT/xfh_update
767 : : !! NAME
768 : : !! xfh_update
769 : : !!
770 : : !! FUNCTION
771 : : !! Update the contents of the history xfhist taking values
772 : : !! from xred, acell, rprim, gred_corrected and strten
773 : : !!
774 : : !! INPUTS
775 : : !!
776 : : !! OUTPUT
777 : : !!
778 : : !! SOURCE
779 : :
780 : 1158 : subroutine xfh_update(ab_xfh,acell,gred_corrected,natom,rprim,strten,xred)
781 : :
782 : : !Arguments ------------------------------------
783 : : !scalars
784 : : type(ab_xfh_type),intent(inout) :: ab_xfh
785 : : integer,intent(in) :: natom
786 : :
787 : : !arrays
788 : : real(dp),intent(in) :: acell(3)
789 : : real(dp),intent(in) :: xred(3,natom)
790 : : real(dp),intent(in) :: rprim(3,3)
791 : : real(dp),intent(in) :: gred_corrected(3,natom)
792 : : real(dp),intent(in) :: strten(6)
793 : :
794 : : !Local variables-------------------------------
795 : : !scalars
796 : : !integer :: kk
797 : :
798 : : !*********************************************************************
799 : :
800 : : !DEBUG
801 : : !write (ab_out,*) '---WROTE TO XFHIST---'
802 : :
803 : : !write (ab_out,*) 'XRED'
804 : : !do kk=1,natom
805 : : !write (ab_out,*) xred(:,kk)
806 : : !end do
807 : : !write (ab_out,*) 'FRED'
808 : : !do kk=1,natom
809 : : !write (ab_out,*) gred_corrected(:,kk)
810 : : !end do
811 : : !write(ab_out,*) 'RPRIM'
812 : : !do kk=1,3
813 : : !write(ab_out,*) rprim(:,kk)
814 : : !end do
815 : : !write(ab_out,*) 'ACELL'
816 : : !write(ab_out,*) acell(:)
817 : : !DEBUG
818 : :
819 : 1158 : ab_xfh%nxfh=ab_xfh%nxfh+1
820 : :
821 [ + + + + ]: 11986 : ab_xfh%xfhist(:,1:natom,1,ab_xfh%nxfh)=xred(:,:)
822 [ + + ]: 4632 : ab_xfh%xfhist(:,natom+1,1,ab_xfh%nxfh)=acell(:)
823 [ + + + + ]: 15054 : ab_xfh%xfhist(:,natom+2:natom+4,1,ab_xfh%nxfh)=rprim(:,:)
824 [ + + + + ]: 11986 : ab_xfh%xfhist(:,1:natom,2,ab_xfh%nxfh)=gred_corrected(:,:)
825 [ + + ]: 4632 : ab_xfh%xfhist(:,natom+2,2,ab_xfh%nxfh)=strten(1:3)
826 [ + + ]: 4632 : ab_xfh%xfhist(:,natom+3,2,ab_xfh%nxfh)=strten(4:6)
827 : :
828 : 1158 : end subroutine xfh_update
829 : : !!***
830 : :
831 : : end module m_xfpack
832 : : !!***
|