Branch data Line data Source code
1 : : !!****m* ABINIT/m_predict_neb
2 : : !! NAME
3 : : !! m_predict_neb
4 : : !!
5 : : !! FUNCTION
6 : : !! This module implement the Nudged Elastic Band method (several variants)
7 : : !!
8 : : !! COPYRIGHT
9 : : !! Copyright (C) 2012-2026 ABINIT group (MT,QD)
10 : : !! This file is distributed under the terms of the
11 : : !! GNU General Public License, see ~abinit/COPYING
12 : : !! or http://www.gnu.org/copyleft/gpl.txt .
13 : : !!
14 : : !! SOURCE
15 : :
16 : : #if defined HAVE_CONFIG_H
17 : : #include "config.h"
18 : : #endif
19 : :
20 : : #include "abi_common.h"
21 : :
22 : : module m_predict_neb
23 : :
24 : : use defs_basis
25 : : use m_splines
26 : : use m_mep
27 : : use m_abicore
28 : : use m_errors
29 : : use m_xmpi
30 : :
31 : : use defs_abitypes, only : MPI_type
32 : : use m_results_img, only : results_img_type, gather_array_img, scatter_array_img, &
33 : : & get_geometry_img
34 : : use m_geometry, only : mkradim, metric, fcart2gred
35 : : use m_matrix, only : matr3inv
36 : :
37 : : implicit none
38 : :
39 : : private
40 : : !!***
41 : :
42 : : public :: predict_neb
43 : : !!***
44 : :
45 : : contains
46 : : !!***
47 : :
48 : : !!****f* ABINIT/predict_neb
49 : : !! NAME
50 : : !! predict_neb
51 : : !!
52 : : !! FUNCTION
53 : : !! Given the past history of images, predict the new set of images using Nudged Elastic Band method.
54 : : !! No change of acell, rprim and vel at present.
55 : : !!
56 : : !! INPUTS
57 : : !! itimimage=time index for image propagation (itimimage+1 is to be predicted here)
58 : : !! itimimage_eff=time index in the history
59 : : !! list_dynimage(nimage)=list of dynamical images. The non-dynamical ones will not change.
60 : : !! Example: in the NEB of string method, one expect the two end images to be fixed.
61 : : !! This is quite useful when ground states of the A and B states is known
62 : : !! mpi_enreg=MPI-parallelisation information
63 : : !! natom=dimension of vel_timimage and xred_timimage
64 : : !! ndynimage=number of dynamical images
65 : : !! nimage=number of images (on current proc)
66 : : !! nimage_tot=total number of images
67 : : !! ntimimage_stored=number of time steps stored in the history
68 : : !!
69 : : !! OUTPUT
70 : : !!
71 : : !! SIDE EFFECTS
72 : : !! mep_param=several parameters for Minimal Energy Path (MEP) search
73 : : !! results_img(ntimimage_stored,nimage)=datastructure that holds the history of previous computations.
74 : : !! results_img(:,:)%acell(3)
75 : : !! at input, history of the values of acell for all images
76 : : !! at output, the predicted values of acell for all images
77 : : !! results_img(:,:)%results_gs
78 : : !! at input, history of the values of energies and forces for all images
79 : : !! results_img(:,:)%rprim(3,3)
80 : : !! at input, history of the values of rprim for all images
81 : : !! at output, the predicted values of rprim for all images
82 : : !! results_img(:,:)%vel(3,natom)
83 : : !! at input, history of the values of vel for all images
84 : : !! at output, the predicted values of vel for all images
85 : : !! results_img(:,:)%vel_cell(3,3)
86 : : !! at input, history of the values of vel_cell for all images
87 : : !! at output, the predicted values of vel_cell for all images
88 : : !! results_img(:,:)%xred(3,natom)
89 : : !! at input, history of the values of xred for all images
90 : : !! at output, the predicted values of xred for all images
91 : : !!
92 : : !! SOURCE
93 : :
94 : 42 : subroutine predict_neb(itimimage,itimimage_eff,list_dynimage,mep_param,mpi_enreg,natom,&
95 : 42 : & ndynimage,nimage,nimage_tot,ntimimage_stored,results_img)
96 : :
97 : : !Arguments ------------------------------------
98 : : !scalars
99 : : integer,intent(in) :: itimimage,itimimage_eff,natom,ndynimage
100 : : integer,intent(in) :: nimage,nimage_tot,ntimimage_stored
101 : : type(mep_type),intent(inout) :: mep_param
102 : : type(MPI_type),intent(in) :: mpi_enreg
103 : : !arrays
104 : : integer,intent(in) :: list_dynimage(ndynimage)
105 : : type(results_img_type),intent(inout) :: results_img(nimage,ntimimage_stored)
106 : :
107 : : !Local variables-------------------------------
108 : : !scalars
109 : : integer :: ierr,ii,jj,iimage,iimage_min,iimage_max,natom_eff,next_itimimage
110 : : logical :: test_minus_one,test_plus_one,use_reduced_coord
111 : : real(dp) :: dvmax,dvmin,ecur,emax,emin,eref,f_para1,f_para2
112 : : character(len=100) :: msg
113 : : !arrays
114 : : integer,parameter :: voigt(3,3)=reshape([1,6,3,6,2,4,3,4,3],[3,3])
115 : : real(dp),parameter :: identity_real(3,3)=reshape([one,zero,zero,zero,one,zero,zero,zero,one],[3,3])
116 : : real(dp) :: mat3_1(3,3),mat3_2(3,3)
117 : 42 : real(dp),allocatable :: acell(:,:),buffer(:,:),buffer_all(:,:)
118 : 42 : real(dp),allocatable :: coordif(:,:,:),dimage(:),spring(:)
119 : 42 : real(dp),allocatable :: rprim(:,:,:),rprimd_start(:,:,:),rprimd_start_inv(:,:,:)
120 : 42 : real(dp),allocatable :: fcart(:,:,:),xcart(:,:,:),xred(:,:,:),strainfact_jj(:)
121 : 42 : real(dp),allocatable :: strten(:,:),strten_mat(:,:,:),rmet(:,:,:),ucvol(:),pressure(:)
122 : 42 : real(dp),allocatable :: tangent(:,:,:),vect(:,:)
123 : 42 : real(dp),allocatable,target :: etotal(:),neb_forces(:,:,:),rprimd(:,:,:)
124 : 42 : real(dp),allocatable,target :: fcart_eff(:,:,:),xcart_eff(:,:,:),xred_eff(:,:,:)
125 : 42 : real(dp),pointer :: coord_(:,:,:),etotal_all(:),fcart_eff_all(:,:,:), neb_forces_all(:,:,:)
126 : 42 : real(dp),pointer :: rprimd_all(:,:,:),xcart_eff_all(:,:,:),xred_eff_all(:,:,:)
127 : :
128 : : ! *************************************************************************
129 : :
130 : : !Check options
131 [ - + ]: 9 : if (mep_param%neb_cell_algo/=NEB_CELL_ALGO_NONE.and.&
132 : : & mep_param%mep_solver/=MEP_SOLVER_STEEPEST) then
133 : 0 : msg='Variable cell NEB only allowed with steepest descent algo!'
134 : 0 : ABI_ERROR(msg)
135 : : end if
136 : :
137 : : !In case of variable-cell, 3 additional "fake" atoms are added to unit cell vectors
138 [ + + ]: 42 : natom_eff=natom ; if (mep_param%neb_cell_algo/=NEB_CELL_ALGO_NONE) natom_eff=natom_eff+3
139 : :
140 : : !VC-NEB uses reduced coordinates
141 : 42 : use_reduced_coord=.false.
142 [ - + ]: 42 : if (mep_param%neb_cell_algo==NEB_CELL_ALGO_VCNEB) use_reduced_coord=.true.
143 : :
144 [ - + + - : 126 : ABI_MALLOC(acell,(3,nimage))
+ - + - -
+ - + ]
145 [ - + + - : 126 : ABI_MALLOC(rprim,(3,3,nimage))
+ - + - -
+ - + ]
146 [ - + + - : 168 : ABI_MALLOC(xred_eff,(3,natom_eff,nimage))
- + + - +
- + - - +
- + ]
147 : :
148 : : !Parallelism over images: only one process per image of the cell
149 [ + - ]: 42 : if (mpi_enreg%me_cell==0) then
150 : :
151 : : ! Retrieve positions and forces
152 [ - + + - : 126 : ABI_MALLOC(etotal,(nimage))
+ - + - -
+ - + ]
153 [ - + + - : 126 : ABI_MALLOC(xcart_eff,(3,natom_eff,nimage))
- + + - -
+ - + ]
154 [ - + + - : 126 : ABI_MALLOC(fcart_eff,(3,natom_eff,nimage))
- + + - -
+ - + ]
155 [ - + + - : 84 : ABI_MALLOC(rprimd,(3,3,nimage))
- + - + ]
156 [ - + + - : 84 : ABI_MALLOC(strainfact_jj,(nimage))
- + - + ]
157 [ + + ]: 316 : strainfact_jj(:)=one
158 [ - + + - : 84 : ABI_MALLOC(rprimd_start,(3,3,nimage))
- + - + ]
159 [ + + ]: 316 : do iimage=1,nimage
160 : 274 : ii=mpi_enreg%my_imgtab(iimage)
161 [ + + + + ]: 3604 : rprimd_start(:,:,iimage)=mep_param%rprimd_start(:,:,ii)
162 : : end do
163 [ - + + - : 168 : ABI_MALLOC(xred,(3,natom,nimage))
- + + - +
- + - - +
- + ]
164 [ - + + - : 126 : ABI_MALLOC(xcart,(3,natom,nimage))
- + + - -
+ - + ]
165 [ - + + - : 126 : ABI_MALLOC(fcart,(3,natom,nimage))
- + + - -
+ - + ]
166 [ - + + - : 126 : ABI_MALLOC(strten,(6,nimage))
+ - + - -
+ - + ]
167 : 42 : call get_geometry_img(results_img(:,itimimage_eff),etotal,natom,nimage,fcart,rprimd,strten,xcart,xred)
168 [ + + + + : 2508 : xred_eff(1:3,1:natom,1:nimage)=xred(1:3,1:natom,1:nimage)
+ + ]
169 [ + + + + : 2508 : xcart_eff(1:3,1:natom,1:nimage)=xcart(1:3,1:natom,1:nimage)
+ + ]
170 [ + + + + : 2508 : fcart_eff(1:3,1:natom,1:nimage)=fcart(1:3,1:natom,1:nimage)
+ + ]
171 : :
172 : : ! Retrieve unit cell vectors and derivatives (forces) in case of variable-cell NEB
173 : : ! => Retrieve pressure, volume, rmet, strten, ...
174 [ + + ]: 42 : if (mep_param%neb_cell_algo/=NEB_CELL_ALGO_NONE) then
175 [ - + + - : 18 : ABI_MALLOC(rmet,(3,3,nimage))
- + - + ]
176 [ - + + - : 18 : ABI_MALLOC(ucvol,(nimage))
- + - + ]
177 [ - + + - : 18 : ABI_MALLOC(pressure,(nimage))
- + - + ]
178 [ - + + - : 18 : ABI_MALLOC(strten_mat,(3,3,nimage))
- + - + ]
179 [ - + + - : 18 : ABI_MALLOC(rprimd_start_inv,(3,3,nimage))
- + - + ]
180 [ + + ]: 72 : pressure(1:nimage)=-(strten(1,1:nimage)+strten(2,1:nimage)+strten(3,1:nimage))*third
181 [ + + ]: 72 : do iimage=1,nimage
182 [ + + + + ]: 819 : xcart_eff(1:3,natom+1:natom+3,iimage)=zero
183 [ + + + + ]: 819 : xred_eff(1:3,natom+1:natom+3,iimage)=zero
184 : 63 : call metric(mat3_1,mat3_2,-1,rmet(:,:,iimage),rprimd(:,:,iimage),ucvol(iimage))
185 [ + + + + ]: 819 : do jj=1,3; do ii=1,3
186 : 756 : strten_mat(ii,jj,iimage)=strten(voigt(ii,jj),iimage)
187 : : end do; end do
188 : 63 : call matr3inv(rprimd_start(:,:,iimage),mat3_1(:,:))
189 [ + + + + ]: 828 : rprimd_start_inv(:,:,iimage) = transpose(mat3_1(:,:))
190 : : end do
191 : :
192 : : ! ==== Generalized Solid-State NEB (GSS-NEB)
193 : : ! See: Sheppard, Xiao, Chemelewski, Johnson, Henkelman, J. Chem. Phys. 136, 074103 (2012)
194 [ + - ]: 9 : if (mep_param%neb_cell_algo==NEB_CELL_ALGO_GSSNEB) then
195 [ + + ]: 72 : strainfact_jj(1:nimage)=(ucvol(1:nimage)**third)*(natom**sixth)
196 [ + + ]: 72 : do iimage=1,nimage
197 [ + + + + ]: 819 : mat3_1(1:3,1:3)=rprimd(1:3,1:3,iimage)-rprimd_start(1:3,1:3,iimage)
198 [ + + + + : 4032 : xcart_eff(1:3,natom+1:natom+3,iimage)=strainfact_jj(iimage)*matmul(rprimd_start_inv(:,:,iimage),mat3_1)
+ + + + +
+ + + +
+ ]
199 [ + + + + ]: 819 : strten_mat(1:3,1:3,iimage)=strten_mat(1:3,1:3,iimage)+pressure(iimage)*identity_real(1:3,1:3)
200 : : fcart_eff(1:3,natom+1:natom+3,iimage)= &
201 [ + + + + ]: 828 : & -(ucvol(iimage)/strainfact_jj(iimage))*strten_mat(1:3,1:3,iimage)
202 : : end do
203 : : end if
204 : :
205 : : ! ==== Variable-cell NEB (VC-NEB, in reduced coordinates) - At present, doesnt work
206 : : ! See: Qian, Dong, Zhou, Tian, Oganov, Wang, Comp. Phys. Comm. 184, 2111 (2013)
207 [ - + ]: 9 : if (mep_param%neb_cell_algo==NEB_CELL_ALGO_VCNEB) then
208 [ # # ]: 0 : do iimage=1,nimage
209 : : xred_eff(1:3,natom+1:natom+3,iimage)= &
210 [ # # # # : 0 : & matmul(rprimd(1:3,1:3,iimage),rprimd_start_inv(1:3,1:3,iimage))-identity_real(1:3,1:3)
# # # # #
# # # #
# ]
211 : 0 : call fcart2gred(fcart(1:3,1:natom,iimage),fcart_eff(1:3,1:natom,iimage),rprimd(1:3,1:3,iimage),natom)
212 [ # # # # : 0 : fcart_eff(1:3,1:natom,iimage)=matmul(rmet(1:3,1:3,iimage),fcart_eff(1:3,1:natom,iimage))
# # # # #
# # # # #
# # # # #
# # # ]
213 [ # # # # ]: 0 : mat3_1(1:3,1:3)=identity_real(1:3,1:3)+transpose(xred_eff(1:3,natom+1:natom+3,iimage))
214 : 0 : call matr3inv(mat3_1,mat3_2)
215 [ # # # # ]: 0 : mat3_1=transpose(mat3_2)
216 [ # # # # ]: 0 : mat3_2(1:3,1:3)=(strten_mat(1:3,1:3,iimage)+pressure(iimage))*identity_real(1:3,1:3)*ucvol(iimage)
217 [ # # # # : 0 : fcart_eff(1:3,natom+1:natom+3,iimage)=-matmul(mat3_2,mat3_1)
# # # # #
# ]
218 : : end do
219 : : end if
220 : :
221 [ - + ]: 9 : ABI_FREE(rmet)
222 [ - + ]: 9 : ABI_FREE(ucvol)
223 [ - + ]: 9 : ABI_FREE(pressure)
224 [ - + ]: 9 : ABI_FREE(strten_mat)
225 [ - + ]: 9 : ABI_FREE(rprimd_start_inv)
226 : : end if
227 : :
228 [ - + ]: 42 : ABI_FREE(xred)
229 [ - + ]: 42 : ABI_FREE(xcart)
230 [ - + ]: 42 : ABI_FREE(fcart)
231 [ - + ]: 42 : ABI_FREE(strten)
232 : :
233 : : ! Array containing effective NEB forces (F_ortho+F_spring)
234 [ - + + - : 126 : ABI_MALLOC(neb_forces,(3,natom_eff,nimage))
- + + - -
+ - + ]
235 : :
236 : : ! Parallelism: gather data of all images
237 [ - + ]: 42 : if (mpi_enreg%paral_img==1) then
238 [ # # # # : 0 : ABI_MALLOC(buffer,(9*natom_eff+10,nimage))
# # # # #
# # # # #
# # # # ]
239 [ # # # # : 0 : ABI_MALLOC(buffer_all,(9*natom_eff+10,nimage_tot))
# # # # #
# # # # #
# # ]
240 [ # # # # : 0 : ABI_MALLOC(etotal_all,(nimage_tot))
# # # # #
# # # ]
241 [ # # # # : 0 : ABI_MALLOC(xcart_eff_all,(3,natom_eff,nimage_tot))
# # # # #
# # # # #
# # ]
242 [ # # # # : 0 : ABI_MALLOC(fcart_eff_all,(3,natom_eff,nimage_tot))
# # # # #
# # # ]
243 [ # # # # : 0 : ABI_MALLOC(xred_eff_all,(3,natom_eff,nimage_tot))
# # # # #
# # # ]
244 [ # # # # : 0 : ABI_MALLOC(rprimd_all,(3,3,nimage_tot))
# # # # #
# # # ]
245 [ # # # # : 0 : ABI_MALLOC(neb_forces_all,(3,natom_eff,nimage_tot))
# # # # #
# # # ]
246 [ # # # # ]: 0 : buffer=zero;ii=0
247 [ # # ]: 0 : buffer(ii+1 ,1:nimage)=etotal(1:nimage);ii=ii+1
248 [ # # # # : 0 : buffer(ii+1:ii+9 ,1:nimage)=reshape(rprimd,(/9,nimage/));ii=ii+9
# # ]
249 [ # # # # : 0 : buffer(ii+1:ii+3*natom_eff,1:nimage)=reshape(xcart_eff,(/3*natom_eff,nimage/));ii=ii+3*natom_eff
# # ]
250 [ # # # # : 0 : buffer(ii+1:ii+3*natom_eff,1:nimage)=reshape(xred_eff,(/3*natom_eff,nimage/));ii=ii+3*natom_eff
# # ]
251 [ # # # # : 0 : buffer(ii+1:ii+3*natom_eff,1:nimage)=reshape(fcart_eff,(/3*natom_eff,nimage/));ii=ii+3*natom_eff
# # ]
252 : 0 : call gather_array_img(buffer,buffer_all,mpi_enreg,allgather=.true.)
253 : 0 : ii=0
254 [ # # ]: 0 : etotal_all(:)=buffer_all(ii+1,1:nimage_tot);ii=ii+1
255 [ # # ]: 0 : rprimd_all(:,:,:)=reshape(buffer_all(ii+1:ii+9,1:nimage_tot),(/3,3,nimage_tot/));ii=ii+9
256 [ # # ]: 0 : xcart_eff_all(:,:,:)=reshape(buffer_all(ii+1:ii+3*natom_eff,1:nimage_tot),(/3,natom_eff,nimage_tot/));ii=ii+3*natom_eff
257 [ # # ]: 0 : xred_eff_all(:,:,:)=reshape(buffer_all(ii+1:ii+3*natom_eff,1:nimage_tot),(/3,natom_eff,nimage_tot/));ii=ii+3*natom_eff
258 [ # # ]: 0 : fcart_eff_all(:,:,:)=reshape(buffer_all(ii+1:ii+3*natom_eff,1:nimage_tot),(/3,natom_eff,nimage_tot/));ii=ii+3*natom_eff
259 [ # # ]: 0 : ABI_FREE(buffer)
260 [ # # ]: 0 : ABI_FREE(buffer_all)
261 : : else
262 : 42 : etotal_all => etotal
263 : 42 : rprimd_all => rprimd
264 : 42 : xcart_eff_all => xcart_eff
265 : 42 : xred_eff_all => xred_eff
266 : 42 : fcart_eff_all => fcart_eff
267 : 42 : neb_forces_all => neb_forces
268 : : end if
269 : :
270 : : ! coordif is the vector between two images
271 : : ! dimage is the distance between two images
272 : : ! tangent is the tangent at image i
273 [ - + + - : 168 : ABI_MALLOC(coordif,(3,natom_eff,nimage_tot))
- + + - +
- + - - +
- + ]
274 [ - + + - : 126 : ABI_MALLOC(tangent,(3,natom_eff,nimage_tot))
- + + - -
+ - + ]
275 [ - + + - : 126 : ABI_MALLOC(dimage,(nimage_tot))
+ - + - -
+ - + ]
276 : :
277 : : ! Compute distances between images
278 [ + + + + ]: 486 : coordif(:,:,1)=zero;dimage(1)=zero
279 [ - + ]: 42 : coord_ => xcart_eff_all ; if (use_reduced_coord) coord_ => xred_eff_all
280 [ + + ]: 274 : do iimage=2,nimage_tot
281 [ + + + + ]: 2778 : coordif(:,:,iimage)=coord_(:,:,iimage)-coord_(:,:,iimage-1)
282 : : end do
283 : :
284 [ + + ]: 274 : do iimage=2,nimage_tot
285 : 274 : dimage(iimage)=mep_img_norm(coordif(:,:,iimage))
286 : : end do
287 : :
288 : : ! Compute tangent (not normalized)
289 [ + + + + ]: 486 : tangent(:,:,1)=zero
290 [ + + + + ]: 486 : tangent(:,:,nimage_tot)=zero
291 : : ! === Original definition of tangent
292 [ + + ]: 42 : if (mep_param%neb_algo==NEB_ALGO_STANDARD) then
293 [ + + ]: 45 : do iimage=2,nimage_tot-1
294 : : tangent(:,:,iimage)=coordif(:,:,iimage )/dimage(iimage) &
295 [ + + + + ]: 333 : & +coordif(:,:,iimage+1)/dimage(iimage+1)
296 : : end do
297 : : ! === Improved tangent (J. Chem. Phys. 113, 9978 (2000) [[cite:Henkelman2000]])
298 : : else
299 [ + + ]: 187 : do iimage=2,nimage_tot-1
300 : 154 : test_minus_one=(etotal_all(iimage-1)<etotal_all(iimage))
301 : 154 : test_plus_one =(etotal_all(iimage )<etotal_all(iimage+1))
302 [ + + ]: 187 : if (test_minus_one.and.test_plus_one)then ! V_i-1 < V_i < V_i+1
303 [ + + + + ]: 729 : tangent(:,:,iimage)=coordif(:,:,iimage+1)
304 [ + + ]: 93 : else if ((.not.test_minus_one).and.(.not.test_plus_one))then ! V_i-1 > V_i > V_i+1
305 [ + + + + ]: 666 : tangent(:,:,iimage)=coordif(:,:,iimage)
306 : : else ! V_i-1 < V_i > V_i+1 OR V_i-1 > V_i < V_i+1
307 : : dvmax=max(abs(etotal_all(iimage+1)-etotal_all(iimage)),&
308 : 39 : & abs(etotal_all(iimage-1)-etotal_all(iimage)))
309 : : dvmin=min(abs(etotal_all(iimage+1)-etotal_all(iimage)),&
310 : 39 : & abs(etotal_all(iimage-1)-etotal_all(iimage)))
311 [ + + ]: 39 : if (etotal_all(iimage+1)>etotal_all(iimage-1)) then ! V_i+1 > V_i-1
312 : : tangent(:,:,iimage)=coordif(:,:,iimage+1)*dvmax &
313 [ + + + + ]: 189 : & +coordif(:,:,iimage )*dvmin
314 : : else ! V_i+1 < V_i-1
315 : : tangent(:,:,iimage)=coordif(:,:,iimage+1)*dvmin &
316 [ + + + + ]: 342 : & +coordif(:,:,iimage )*dvmax
317 : : end if
318 : : end if
319 : : end do
320 : : end if
321 : :
322 : : ! Normalize tangent
323 [ + + ]: 232 : do iimage=2,nimage_tot-1
324 [ + + + + ]: 2292 : tangent(:,:,iimage)=tangent(:,:,iimage)/mep_img_norm(tangent(:,:,iimage))
325 : : end do
326 : :
327 : : ! Compute spring constant(s)
328 [ - + + - : 84 : ABI_MALLOC(spring,(nimage_tot))
- + - + ]
329 [ + - ]: 42 : if (abs(mep_param%neb_spring(2)-mep_param%neb_spring(1))<tol8) then ! Constant spring
330 [ + + ]: 316 : spring(:)=mep_param%neb_spring(1)
331 : : else ! Variable spring
332 [ # # # # : 0 : emax=maxval(etotal_all(:))
# # # # ]
333 : 0 : eref=max(etotal_all(1),etotal_all(nimage_tot))
334 [ # # ]: 0 : spring(:)=mep_param%neb_spring(1)
335 [ # # ]: 0 : do iimage=2,nimage_tot-1
336 : 0 : ecur=max(etotal_all(iimage-1),etotal_all(iimage))
337 [ # # ]: 0 : if (ecur<eref) then
338 : 0 : spring(iimage)=mep_param%neb_spring(1)
339 : : else
340 : : spring(iimage)=mep_param%neb_spring(2) &
341 : : & -(mep_param%neb_spring(2)-mep_param%neb_spring(1)) &
342 : 0 : & *(emax-ecur)/(emax-eref)
343 : : end if
344 : : end do
345 : : end if
346 : :
347 : : ! CI-NEB: determine image(s) with maximal energy
348 : 42 : iimage_min=-1;iimage_max=-1
349 [ + + + + ]: 42 : if (mep_param%neb_algo==NEB_ALGO_CINEB.and.itimimage>=mep_param%cineb_start) then
350 : 7 : emin=min(etotal_all(1),etotal_all(nimage_tot))
351 : 7 : emax=max(etotal_all(1),etotal_all(nimage_tot))
352 [ + + ]: 42 : do iimage=2,nimage_tot-1
353 : 35 : if (etotal_all(iimage)<emin) then
354 : : iimage_min=iimage;emin=etotal_all(iimage)
355 : : end if
356 [ + + ]: 42 : if (etotal_all(iimage)>emax) then
357 : 21 : iimage_max=iimage;emax=etotal_all(iimage)
358 : : end if
359 : : end do
360 : : end if
361 : :
362 : : ! Compute NEB forces
363 [ + - + + : 930 : neb_forces_all(:,:,1)=fcart_eff_all(:,:,1)
+ + + + +
+ ]
364 [ + + + + : 930 : neb_forces_all(:,:,nimage_tot)=fcart_eff_all(:,:,nimage_tot)
+ + + + ]
365 [ + + ]: 232 : do iimage=2,nimage_tot-1
366 : : ! === Standard NEB
367 [ + + ]: 232 : if (iimage/=iimage_max) then
368 : : ! if (iimage/=iimage_min.and.iimage/=iimage_max) then
369 : 183 : f_para1=mep_img_dotp(fcart_eff_all(:,:,iimage),tangent(:,:,iimage))
370 [ + + ]: 183 : if (mep_param%neb_algo==NEB_ALGO_STANDARD) then ! Original NEB algo
371 [ - + + - : 108 : ABI_MALLOC(vect,(3,natom_eff))
+ - + - -
+ - + ]
372 [ + + + + ]: 324 : vect(:,:)=spring(iimage+1)*coordif(:,:,iimage+1)-spring(iimage)*coordif(:,:,iimage)
373 : 36 : f_para2=mep_img_dotp(vect(:,:),tangent(:,:,iimage))
374 [ - + ]: 36 : ABI_FREE(vect)
375 : : else ! Modification from J. Chem. Phys. 113, 9978 (2000) [[cite:Henkelman2000]]
376 : 147 : f_para2=spring(iimage+1)*dimage(iimage+1)-spring(iimage)*dimage(iimage)
377 : : end if
378 : : neb_forces_all(:,:,iimage)=fcart_eff_all(:,:,iimage) & ! F_ortho
379 : : & -f_para1*tangent(:,:,iimage) & ! F_ortho
380 [ + + + + : 4191 : & +f_para2*tangent(:,:,iimage) ! F_spring
+ + + + ]
381 : : ! === CI-NEB for the image(s) with maximal energy
382 : : else
383 : 7 : f_para1=mep_img_dotp(fcart_eff_all(:,:,iimage),tangent(:,:,iimage))
384 [ + + + + : 119 : neb_forces_all(:,:,iimage)=fcart_eff_all(:,:,iimage)-two*f_para1*tangent(:,:,iimage)
+ + + + ]
385 : : end if
386 : : end do
387 : :
388 : : ! Parallelism: distribute NEB forces
389 [ - + ]: 42 : if (mpi_enreg%paral_img==1) then
390 [ # # ]: 0 : do iimage=1,nimage
391 : 0 : ii=mpi_enreg%my_imgtab(iimage)
392 [ # # # # : 0 : neb_forces(:,:,iimage)=neb_forces_all(:,:,ii)
# # # # ]
393 : : end do
394 : : end if
395 : :
396 : : ! Compute new atomic positions in each cell
397 [ + - ]: 42 : if (mep_param%mep_solver==MEP_SOLVER_STEEPEST) then ! Steepest-descent
398 : : call mep_steepest(neb_forces,list_dynimage,mep_param,natom,natom_eff,&
399 : : & ndynimage,nimage,rprimd,xcart_eff,xred_eff,&
400 : : & strainfact=strainfact_jj,rprimd_start=rprimd_start,&
401 : 42 : & use_reduced_coord=use_reduced_coord)
402 [ # # ]: 0 : else if (mep_param%mep_solver==MEP_SOLVER_QUICKMIN) then ! Quick-min
403 : : call mep_qmin(neb_forces,itimimage,list_dynimage,mep_param,natom,ndynimage, &
404 : 0 : & nimage,rprimd,xcart_eff,xred_eff)
405 [ # # ]: 0 : else if (mep_param%mep_solver==MEP_SOLVER_LBFGS) then ! Local BFGS
406 : : call mep_lbfgs(neb_forces,itimimage,list_dynimage,mep_param,natom,ndynimage,&
407 : 0 : & nimage,rprimd,xcart_eff,xred_eff)
408 [ # # ]: 0 : else if (mep_param%mep_solver==MEP_SOLVER_GBFGS) then ! Global BFGS
409 : : call mep_gbfgs(neb_forces,itimimage,list_dynimage,mep_param,mpi_enreg,natom,ndynimage,&
410 : 0 : & nimage,nimage_tot,rprimd,xcart_eff,xred_eff)
411 : : else
412 : 0 : ABI_BUG("Inconsistent solver !")
413 : : end if
414 : :
415 : : ! Compute new acell and rprim from new rprimd
416 : : !if (mep_param%neb_cell_algo/=NEB_CELL_ALGO_NONE) then
417 [ + + ]: 316 : do iimage=1,nimage
418 : 316 : call mkradim(acell(:,iimage),rprim(:,:,iimage),rprimd(:,:,iimage))
419 : : end do
420 : : !end if
421 : :
422 : : ! Free memory
423 [ - + ]: 42 : ABI_FREE(spring)
424 [ - + ]: 42 : ABI_FREE(coordif)
425 [ - + ]: 42 : ABI_FREE(tangent)
426 : 42 : ABI_FREE(dimage)
427 [ - + ]: 42 : if (mpi_enreg%paral_img==1) then
428 [ # # ]: 0 : ABI_FREE(etotal_all)
429 [ # # ]: 0 : ABI_FREE(rprimd_all)
430 [ # # ]: 0 : ABI_FREE(xred_eff_all)
431 [ # # ]: 0 : ABI_FREE(xcart_eff_all)
432 [ # # ]: 0 : ABI_FREE(fcart_eff_all)
433 [ # # ]: 0 : ABI_FREE(neb_forces_all)
434 : : end if
435 : :
436 [ - + ]: 42 : ABI_FREE(neb_forces)
437 [ - + ]: 42 : ABI_FREE(etotal)
438 [ - + ]: 42 : ABI_FREE(rprimd)
439 [ - + ]: 42 : ABI_FREE(xcart_eff)
440 [ - + ]: 42 : ABI_FREE(fcart_eff)
441 [ - + ]: 42 : ABI_FREE(strainfact_jj)
442 [ - + ]: 42 : ABI_FREE(rprimd_start)
443 : :
444 : : end if ! mpi_enreg%me_cell==0
445 : :
446 : : !Store acell, rprim, xred and vel for the new iteration
447 : 42 : call xmpi_bcast(xred_eff,0,mpi_enreg%comm_cell,ierr)
448 : 42 : call xmpi_bcast(acell,0,mpi_enreg%comm_cell,ierr)
449 : 42 : call xmpi_bcast(rprim,0,mpi_enreg%comm_cell,ierr)
450 : 42 : next_itimimage=itimimage_eff+1
451 [ - + ]: 42 : if (next_itimimage>ntimimage_stored) next_itimimage=1
452 [ + + ]: 316 : do iimage=1,nimage
453 [ + + + + ]: 2466 : results_img(iimage,next_itimimage)%xred(:,1:natom)=xred_eff(:,1:natom,iimage)
454 [ + + ]: 274 : if (mep_param%neb_cell_algo==NEB_CELL_ALGO_NONE) then
455 [ + + ]: 844 : results_img(iimage,next_itimimage)%acell(:) =results_img(iimage,itimimage_eff)%acell(:)
456 [ + + + + ]: 2743 : results_img(iimage,next_itimimage)%rprim(:,:) =results_img(iimage,itimimage_eff)%rprim(:,:)
457 : : else
458 [ + + ]: 252 : results_img(iimage,next_itimimage)%acell(:) =acell(:,iimage)
459 [ + + + + ]: 819 : results_img(iimage,next_itimimage)%rprim(:,:) =rprim(:,:,iimage)
460 : : end if
461 [ + + + + ]: 2466 : results_img(iimage,next_itimimage)%vel(:,:) =results_img(iimage,itimimage_eff)%vel(:,:)
462 [ + + + + ]: 3604 : results_img(iimage,next_itimimage)%vel_cell(:,:)=results_img(iimage,itimimage_eff)%vel_cell(:,:)
463 : : end do
464 : :
465 [ - + ]: 42 : ABI_FREE(xred_eff)
466 [ - + ]: 42 : ABI_FREE(acell)
467 [ - + ]: 42 : ABI_FREE(rprim)
468 : :
469 [ + + - + : 84 : end subroutine predict_neb
- + - + -
+ - + ]
470 : : !!***
471 : :
472 : : end module m_predict_neb
473 : : !!***
|