TABLE OF CONTENTS


ABINIT/aim_follow [ Functions ]

[ Top ] [ Functions ]

NAME

 aim_follow

FUNCTION

 This routine follows the gradient line starting from the point
 vv. It stop when it arrives to the atom (nearer than rminl(iat))
 or - if srch=true - also if it arrives under the already known
 part of Bader surface

COPYRIGHT

 Copyright (C) 2002-2017 ABINIT group (PCasek,FF,XG)
 This file is distributed under the terms of the
 GNU General Public License, see ~abinit/COPYING
 or http://www.gnu.org/copyleft/gpl.txt .
 For the initials of contributors, see ~abinit/doc/developers/contributors.txt .

 WARNING
 This file does not follow the ABINIT coding rules (yet)

INPUTS

 aim_dtset= the structured entity containing all input variables
 iatinit,iposinit= indexes of initial atom
 npmax= maximum number of division in each step

OUTPUT

 iat,ipos= index of final atom
 nstep= returns the number of step needed

SIDE EFFECTS

 srch=  (true/false) check if the line is outside or
             inside the atomic surface.
 vv(3)= initial point in orthogonal coordinates

PARENTS

      cpdrv,drvaim,rsurf

CHILDREN

      critic,onestep,timein,vgh_rho

SOURCE

 44 #if defined HAVE_CONFIG_H
 45 #include "config.h"
 46 #endif
 47 
 48 #include "abi_common.h"
 49 
 50 
 51 subroutine aim_follow(aim_dtset,vv,npmax,srch,iatinit,iposinit,iat,ipos,nstep)
 52 
 53  use defs_basis
 54  use defs_aimprom
 55  use defs_parameters
 56  use defs_abitypes
 57  use m_errors
 58  use m_profiling_abi
 59 
 60 !This section has been created automatically by the script Abilint (TD).
 61 !Do not modify the following lines by hand.
 62 #undef ABI_FUNC
 63 #define ABI_FUNC 'aim_follow'
 64  use interfaces_18_timing
 65  use interfaces_63_bader, except_this_one => aim_follow
 66 !End of the abilint section
 67 
 68  implicit none
 69 
 70 !Arguments ------------------------------------
 71 !scalars
 72  integer,intent(in) :: iatinit,iposinit,npmax
 73  integer,intent(out) :: iat,ipos,nstep
 74  logical,intent(inout) :: srch
 75  type(aim_dataset_type),intent(in) :: aim_dtset
 76 !arrays
 77  real(dp),intent(inout) :: vv(3)
 78 
 79 !Local variables ------------------------------
 80 !scalars
 81  integer :: i1,i2,i3,ii,iph,ires,ith,jj,kk,nit,np,nph,nsi,nth
 82  real(dp) :: deltar,dg,dist,dph,dth,fac2,facf,h0old,hh,hold,rho,rr,rsmed
 83  real(dp) :: t1,t2,t3,vcth,vph,vth,wall,xy,xyz
 84  logical :: fin,ldebold,srchold,stemp,stemp2
 85  character(len=50) :: formpc
 86  character(len=500) :: msg
 87 !arrays
 88  real(dp) :: ev(3),grho(3),hrho(3,3),pom(3),vold(3),vt(3),vt1(3)
 89  real(dp) :: zz(3,3)
 90 
 91 !************************************************************************
 92  formpc='(":CP",2I5,3F12.8,3E12.4,I4,2E12.4)'
 93 
 94 
 95  fin=.false.
 96 
 97  srchold=srch
 98  ldebold=ldeb
 99  h0old=h0
100 
101  nth=aim_dtset%nth
102  nph=aim_dtset%nph
103 
104  if (slc==0) then
105    rminl(:)=aim_dtset%rmin
106  end if
107 
108  if (deb) then
109    ldeb=.true.
110  end if
111 
112  call vgh_rho(vv,rho,grho,hrho,rr,iat,ipos,slc)
113 
114 !Initial tests
115 
116  if (iat/=0) then
117    if (rr<rminl(iat)) then
118      fin=.true.
119      write(std_out,*) 'rr < rmin iat=',iat,' ipos=',ipos
120    elseif (rho<aim_rhomin) then
121      fin=.true.
122      write(std_out,*) 'CHARGE LT rhomin ',rho,' < ',aim_rhomin
123      if (rho<zero) then 
124        MSG_ERROR('RHO < 0 !!!')
125      end if
126    end if
127  end if
128 
129  facf=aim_fac0
130  hh=aim_hmax
131 
132  call timein(t1,wall)
133  nstep=0
134  nsi=0
135 
136 !the principal cycle
137 
138  madw : do while(.not.fin)
139    hold=hh
140 
141    dg=vnorm(grho,0)
142    if (ldeb.or.deb) write(std_out,*) 'dg= ',dg
143 
144 !  the time test
145 
146    call timein(t3,wall)
147    t2=t3-t1
148    if (t2>300.0) then
149      write(std_out,*) 'TIME EXCEEDED 5 min IN FOLLOW'
150      write(std_out,*) 'h0 =',h0,'  h =',hh,'  h0old =',h0old,'  dg =',dg
151      write(std_out,*) 'facf =',facf
152      msg =  'TIME EXCEEDED 5 min IN FOLLOW'
153      MSG_ERROR(msg)
154    end if
155 
156    if (dg<aim_dgmin) then
157      write(std_out,*) 'gradient < dgmin ',dg,' < ',aim_dgmin
158      fin=.true.
159      iat=0
160      ipos=0
161 !    testing for the CP
162      if (npc>0) then
163        call critic(aim_dtset,vv,ev,zz,aim_dmaxcrit,ires,0)
164        if (ires==0) then
165          do jj=1,npc
166            pom(:)=pc(:,jj)-vv(:)+xatm(:,aim_dtset%batom)
167            dist=vnorm(pom,0)
168            if (dist<aim_tiny) cycle madw
169          end do
170          write(std_out,*) 'C.P. found !!'
171          npc=npc+1
172          do jj=1,3
173            pc(jj,npc)=vv(jj)
174            evpc(jj,npc)=ev(jj)
175            do kk=1,3
176              zpc(kk,jj,npc)=zz(kk,jj)
177            end do
178          end do
179          i1=ev(1)/abs(ev(1))
180          i2=ev(2)/abs(ev(2))
181          i3=ev(3)/abs(ev(3))
182          icpc(npc)=i1+i2+i3
183          if (icpc(npc)==-3) then           ! pseudoatom handling
184            npcm3=npcm3+1
185            write(std_out,*) 'Pseudo-atom found !!'
186          end if
187 
188          call vgh_rho(vv,rho,grho,hrho,rr,iat,ipos,slc)
189          write(22,formpc) 0,0,(pcrb(jj,npc),jj=1,3),(ev(jj),jj=1,3),icpc(npc),&
190 &         ev(1)+ev(2)+ev(3),rho
191          write(std_out,formpc) 0,0,(pcrb(jj,npc),jj=1,3),(ev(jj),jj=1,3),icpc(npc),&
192 &         ev(1)+ev(2)+ev(3),rho
193        else
194          write(std_out,*) 'C.P. not found !!'
195        end if
196      end if
197 
198      cycle madw
199    end if
200 
201    hh=h0/dg
202    if (ldeb.or.deb) write(std_out,*) 'h= ',hh,' h0= ',h0,' dg= ',dg
203    if (hh>aim_hmax) hh=aim_hmax
204 !  step modifications
205 
206    hh=hh*facf
207    if (hh>(hold*aim_hmult)) then
208      hh=hold*aim_hmult
209    end if
210 
211    do ii=1,3
212      vold(ii)=vv(ii)
213    end do
214 
215    nit=0
216    hold=hh
217 
218 !  one step following the gradient line
219 !  
220    call onestep(vv,rho,grho,hh,np,npmax,deltar)
221    do while (((np>npmax).or.(deltar>aim_stmax)).and.(deltar>aim_dmin))
222      nit=nit+1
223      if (nit>5) then
224        if (deltar>aim_stmax) then
225          write(std_out,*) 'nit > 5 and deltar > stmax   nit=',nit
226        else
227          write(std_out,*) 'nit > 5 and np > npmax   nit=',nit
228        end if
229      end if
230      do ii=1,3
231        vv(ii)=vold(ii)
232      end do
233      hh=hh*0.3
234      call onestep(vv,rho,grho,hh,np,npmax,deltar)
235    end do
236 
237 
238    nstep=nstep+1
239    if (ldeb.or.deb) write(std_out,*) 'h= ',hh
240 
241    fac2=hh/hold
242    if (fac2>=1._dp) then
243      facf=facf*1.2
244    else
245      if (fac2>=aim_facmin) then
246        facf=fac2
247      else
248        facf=aim_facmin
249      end if
250    end if
251 
252    if (deb.or.ldeb) then
253      write(std_out,*) ':POS ',vv
254      write(std_out,*) ':RBPOS ',vt1
255      write(std_out,*) ':GRAD ',grho
256    end if
257 
258    call vgh_rho(vv,rho,grho,hrho,rr,iat,ipos,slc)
259    dg=vnorm(grho,0)
260    pom(:)=vv(:)-xatm(:,iatinit)-atp(:,iposinit)
261 
262    if (iat /= 0) then
263      fin=.true.
264      write(std_out,*) 'r < rmin iat=',iat,' ipos=',ipos
265      cycle madw
266    end if
267 
268    if (rho<aim_rhomin) then
269      fin=.true.
270      write(std_out,*) 'charge < rhomin ',rho,' < ',aim_rhomin
271      if (rho<zero) then 
272        MSG_ERROR('RHO < 0 !!!')
273      end if
274      iat=0
275      ipos=0
276      cycle madw
277    end if
278 
279    if (npcm3>0) then
280      do jj=1,npc
281        if (icpc(jj)==(-3)) then
282          pom(:)=pc(:,jj)-vv(:)+xatm(:,aim_dtset%batom)
283          dist=vnorm(pom,0)
284          if (dist<(aim_dtset%rmin**2*0.1)) then
285            iat=0
286            ipos=0
287            fin=.true.
288            write(std_out,*) 'We are inside a pseudo-atom'
289            cycle madw
290          end if
291        end if
292      end do
293    end if
294 
295    nsi=nsi+1
296 
297 !  surface checking
298 
299    if (srch.and.(nsi>=nsimax)) then
300      nsi=0
301      ith=0
302      iph=0
303      do ii=1,3
304        vt(ii)=vv(ii)-xatm(ii,iatinit)
305      end do
306      xy=vt(1)*vt(1)+vt(2)*vt(2)
307      xyz=xy+vt(3)*vt(3)
308      xyz=sqrt(xyz)
309      if (xy<aim_snull) then
310        vcth=1._dp
311        if (vt(3)<0._dp) vcth=-vcth
312        vph=0._dp
313      else
314        vcth=vt(3)/xyz
315        vph=atan2(vt(2),vt(1))
316      end if
317      vth=acos(vcth)
318      if (vth<th(1)) then
319        ith=0
320      else
321        if (vth>th(nth)) then
322          ith=nth
323        else
324          do ii=2,nth
325            if (vth<th(ii)) then
326              ith=ii-1
327              exit
328            end if
329          end do
330        end if
331      end if
332 
333      if (vph<ph(1)) then
334        iph=0
335      else
336        if (vph>ph(nph)) then
337          iph=nph
338        else
339          do ii=2,nph
340            if (vph<ph(ii)) then
341              iph=ii-1
342              exit
343            end if
344          end do
345        end if
346      end if
347 
348      stemp=(iph>0).and.(iph<nph)
349      stemp=stemp.and.(ith>0).and.(ith<nth)
350 
351      if (stemp) then
352        stemp2=rs(ith,iph)>0._dp
353        stemp2=stemp2.and.(rs(ith+1,iph)>0._dp)
354        stemp2=stemp2.and.(rs(ith+1,iph+1)>0._dp)
355        stemp2=stemp2.and.(rs(ith,iph+1)>0._dp)
356        if (stemp2) then
357          dth=th(ith+1)-th(ith)
358          dph=ph(iph+1)-ph(iph)
359          rsmed=rs(ith,iph)*(th(ith+1)-vth)/dth*(ph(iph+1)-vph)/dph
360          rsmed=rsmed+rs(ith+1,iph)*(vth-th(ith))/dth*(ph(iph+1)-vph)/dph
361          rsmed=rsmed+rs(ith+1,iph+1)*(vth-th(ith))/dth*(vph-ph(iph))/dph
362          rsmed=rsmed+rs(ith,iph+1)*(th(ith+1)-vth)/dth*(vph-ph(iph))/dph
363          if (rsmed>xyz) then
364            write(std_out,*) 'We are inside the surface'
365            iat=iatinit
366            ipos=iposinit
367          else
368            write(std_out,*) 'We are outside the surface'
369            iat=0
370            ipos=0
371          end if
372          fin=.true.
373          cycle madw
374        end if
375      end if
376    end if
377 
378  end do madw
379 
380 
381  srch=srchold
382  ldeb=ldebold
383  h0=h0old
384 
385 
386 end subroutine aim_follow