ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE-4/src/UseTheForce/DarkSide/eam.F90
(Generate patch)

Comparing trunk/OOPSE-4/src/UseTheForce/DarkSide/eam.F90 (file contents):
Revision 2278 by chrisfen, Fri Aug 26 22:39:25 2005 UTC vs.
Revision 2722 by gezelter, Thu Apr 20 18:24:24 2006 UTC

# Line 45 | Line 45 | module eam
45    use status
46    use atype_module
47    use vector_class
48 +  use interpolation
49   #ifdef IS_MPI
50    use mpiSimulation
51   #endif
52    implicit none
53    PRIVATE
54 + #define __FORTRAN90
55 + #include "UseTheForce/DarkSide/fInteractionMap.h"
56  
57    INTEGER, PARAMETER :: DP = selected_real_kind(15)
58  
# Line 65 | Line 68 | module eam
68    character(len=*), parameter :: RoutineName =  "EAM MODULE"
69    !! Logical that determines if eam arrays should be zeroed
70    logical :: cleanme = .true.
68  logical :: nmflag  = .false.
71  
70
72    type, private :: EAMtype
73       integer           :: eam_atype      
73     real( kind = DP ) :: eam_dr          
74     integer           :: eam_nr          
75     integer           :: eam_nrho          
74       real( kind = DP ) :: eam_lattice        
77     real( kind = DP ) :: eam_drho      
75       real( kind = DP ) :: eam_rcut    
76       integer           :: eam_atype_map
77 <
78 <     real( kind = DP ), pointer, dimension(:) :: eam_rvals        => null()
79 <     real( kind = DP ), pointer, dimension(:) :: eam_rhovals      => null()
80 <     real( kind = DP ), pointer, dimension(:) :: eam_F_rho        => null()
84 <     real( kind = DP ), pointer, dimension(:) :: eam_Z_r          => null()
85 <     real( kind = DP ), pointer, dimension(:) :: eam_rho_r        => null()
86 <     real( kind = DP ), pointer, dimension(:) :: eam_phi_r        => null()
87 <     real( kind = DP ), pointer, dimension(:) :: eam_F_rho_pp     => null()
88 <     real( kind = DP ), pointer, dimension(:) :: eam_Z_r_pp       => null()
89 <     real( kind = DP ), pointer, dimension(:) :: eam_rho_r_pp     => null()
90 <     real( kind = DP ), pointer, dimension(:) :: eam_phi_r_pp     => null()
77 >     type(cubicSpline) :: rho
78 >     type(cubicSpline) :: Z
79 >     type(cubicSpline) :: F
80 >     type(cubicSpline) :: phi
81    end type EAMtype
82  
93
83    !! Arrays for derivatives used in force calculation
84    real( kind = dp), dimension(:), allocatable :: frho
85    real( kind = dp), dimension(:), allocatable :: rho
97
86    real( kind = dp), dimension(:), allocatable :: dfrhodrho
99  real( kind = dp), dimension(:), allocatable :: d2frhodrhodrho
87  
101
88    !! Arrays for MPI storage
89   #ifdef IS_MPI
90    real( kind = dp),save, dimension(:), allocatable :: dfrhodrho_col
# Line 108 | Line 94 | module eam
94    real( kind = dp),save, dimension(:), allocatable :: rho_row
95    real( kind = dp),save, dimension(:), allocatable :: rho_col
96    real( kind = dp),save, dimension(:), allocatable :: rho_tmp
111  real( kind = dp),save, dimension(:), allocatable :: d2frhodrhodrho_col
112  real( kind = dp),save, dimension(:), allocatable :: d2frhodrhodrho_row
97   #endif
98  
99    type, private :: EAMTypeList
# Line 120 | Line 104 | module eam
104       integer, pointer         :: atidToEAMType(:) => null()
105    end type EAMTypeList
106  
123
107    type (eamTypeList), save :: EAMList
108  
109    !! standard eam stuff  
# Line 138 | Line 121 | contains
121  
122   contains
123  
141
124    subroutine newEAMtype(lattice_constant,eam_nrho,eam_drho,eam_nr,&
125 <       eam_dr,rcut,eam_Z_r,eam_rho_r,eam_F_rho,&
144 <       c_ident,status)
125 >       eam_dr,rcut,eam_Z_r,eam_rho_r,eam_F_rho, c_ident, status)
126      real (kind = dp )                      :: lattice_constant
127      integer                                :: eam_nrho
128      real (kind = dp )                      :: eam_drho
129      integer                                :: eam_nr
130      real (kind = dp )                      :: eam_dr
131      real (kind = dp )                      :: rcut
132 <    real (kind = dp ), dimension(eam_nr)   :: eam_Z_r
133 <    real (kind = dp ), dimension(eam_nr)   :: eam_rho_r
134 <    real (kind = dp ), dimension(eam_nrho) :: eam_F_rho
132 >    real (kind = dp ), dimension(eam_nr)   :: eam_Z_r, rvals
133 >    real (kind = dp ), dimension(eam_nr)   :: eam_rho_r, eam_phi_r
134 >    real (kind = dp ), dimension(eam_nrho) :: eam_F_rho, rhovals
135      integer                                :: c_ident
136      integer                                :: status
137  
138      integer                                :: nAtypes,nEAMTypes,myATID
139      integer                                :: maxVals
140      integer                                :: alloc_stat
141 <    integer                                :: current
141 >    integer                                :: current, j
142      integer,pointer                        :: Matchlist(:) => null()
143  
144      status = 0
145  
165
146      !! Assume that atypes has already been set and get the total number of types in atypes
147      !! Also assume that every member of atypes is a EAM model.
148  
169
149      ! check to see if this is the first time into
150      if (.not.associated(EAMList%EAMParams)) then
151         call getMatchingElementList(atypes, "is_EAM", .true., nEAMtypes, MatchList)
# Line 182 | Line 161 | contains
161      myATID =  getFirstMatchingElement(atypes, "c_ident", c_ident)
162      EAMList%atidToEAMType(myATID) = current
163  
185    call allocate_EAMType(eam_nrho,eam_nr,EAMList%EAMParams(current),stat=alloc_stat)
186    if (alloc_stat /= 0) then
187       status = -1
188       return
189    end if
190
191  
164      EAMList%EAMParams(current)%eam_atype    = c_ident
165      EAMList%EAMParams(current)%eam_lattice  = lattice_constant
194    EAMList%EAMParams(current)%eam_nrho     = eam_nrho
195    EAMList%EAMParams(current)%eam_drho     = eam_drho
196    EAMList%EAMParams(current)%eam_nr       = eam_nr
197    EAMList%EAMParams(current)%eam_dr       = eam_dr
166      EAMList%EAMParams(current)%eam_rcut     = rcut
199    EAMList%EAMParams(current)%eam_Z_r      = eam_Z_r
200    EAMList%EAMParams(current)%eam_rho_r    = eam_rho_r
201    EAMList%EAMParams(current)%eam_F_rho    = eam_F_rho
167  
168 +    ! Build array of r values
169 +    do j = 1, eam_nr
170 +       rvals(j) = real(j-1,kind=dp) * eam_dr
171 +    end do
172 +    
173 +    ! Build array of rho values
174 +    do j = 1, eam_nrho
175 +       rhovals(j) = real(j-1,kind=dp) * eam_drho
176 +    end do
177 +
178 +    ! convert from eV to kcal / mol:
179 +    do j = 1, eam_nrho
180 +       eam_F_rho(j) = eam_F_rho(j) * 23.06054E0_DP
181 +    end do
182 +    
183 +    ! precompute the pair potential and get it into kcal / mol:
184 +    eam_phi_r(1) = 0.0E0_DP
185 +    do j = 2, eam_nr
186 +       eam_phi_r(j) = 331.999296E0_DP * (eam_Z_r(j)**2) / rvals(j)
187 +    enddo
188 +
189 +    call newSpline(EAMList%EAMParams(current)%rho, rvals, eam_rho_r, .true.)
190 +    call newSpline(EAMList%EAMParams(current)%Z,   rvals, eam_Z_r, .true.)
191 +    call newSpline(EAMList%EAMParams(current)%F, rhovals, eam_F_rho, .true.)
192 +    call newSpline(EAMList%EAMParams(current)%phi, rvals, eam_phi_r, .true.)
193    end subroutine newEAMtype
194  
195  
# Line 217 | Line 207 | contains
207  
208      eamList%n_eam_types = 0
209      eamList%currentAddition = 0
220
210    end subroutine destroyEAMtypes
211  
212    function getEAMCut(atomID) result(cutValue)
# Line 227 | Line 216 | contains
216      
217      eamID = EAMList%atidToEAMType(atomID)
218      cutValue = EAMList%EAMParams(eamID)%eam_rcut
230
219    end function getEAMCut
220  
221    subroutine init_EAM_FF(status)
222      integer :: status
223      integer :: i,j
224      real(kind=dp) :: current_rcut_max
225 + #ifdef IS_MPI
226 +    integer :: nAtomsInRow
227 +    integer :: nAtomsInCol
228 + #endif
229      integer :: alloc_stat
230      integer :: number_r, number_rho
231  
240
232      status = 0
233      if (EAMList%currentAddition == 0) then
234         call handleError("init_EAM_FF","No members in EAMList")
235         status = -1
236         return
237      end if
238 <
248 <
249 <    do i = 1, EAMList%currentAddition
250 <
251 <       ! Build array of r values
252 <
253 <       do j = 1,EAMList%EAMParams(i)%eam_nr
254 <          EAMList%EAMParams(i)%eam_rvals(j) = &
255 <               real(j-1,kind=dp)* &
256 <               EAMList%EAMParams(i)%eam_dr
257 <       end do
258 <       ! Build array of rho values
259 <       do j = 1,EAMList%EAMParams(i)%eam_nrho
260 <          EAMList%EAMParams(i)%eam_rhovals(j) = &
261 <               real(j-1,kind=dp)* &
262 <               EAMList%EAMParams(i)%eam_drho
263 <       end do
264 <       ! convert from eV to kcal / mol:
265 <       EAMList%EAMParams(i)%eam_F_rho = EAMList%EAMParams(i)%eam_F_rho * 23.06054E0_DP
266 <
267 <       ! precompute the pair potential and get it into kcal / mol:
268 <       EAMList%EAMParams(i)%eam_phi_r(1) = 0.0E0_DP
269 <       do j = 2, EAMList%EAMParams(i)%eam_nr
270 <          EAMList%EAMParams(i)%eam_phi_r(j) = (EAMList%EAMParams(i)%eam_Z_r(j)**2)/EAMList%EAMParams(i)%eam_rvals(j)
271 <          EAMList%EAMParams(i)%eam_phi_r(j) =  EAMList%EAMParams(i)%eam_phi_r(j)*331.999296E0_DP
272 <       enddo
273 <    end do
274 <
275 <
276 <    do i = 1,  EAMList%currentAddition
277 <       number_r   = EAMList%EAMParams(i)%eam_nr
278 <       number_rho = EAMList%EAMParams(i)%eam_nrho
279 <
280 <       call eam_spline(number_r, EAMList%EAMParams(i)%eam_rvals, &
281 <            EAMList%EAMParams(i)%eam_rho_r, &
282 <            EAMList%EAMParams(i)%eam_rho_r_pp, &
283 <            0.0E0_DP, 0.0E0_DP, 'N')
284 <       call eam_spline(number_r, EAMList%EAMParams(i)%eam_rvals, &
285 <            EAMList%EAMParams(i)%eam_Z_r, &
286 <            EAMList%EAMParams(i)%eam_Z_r_pp, &
287 <            0.0E0_DP, 0.0E0_DP, 'N')
288 <       call eam_spline(number_rho, EAMList%EAMParams(i)%eam_rhovals, &
289 <            EAMList%EAMParams(i)%eam_F_rho, &
290 <            EAMList%EAMParams(i)%eam_F_rho_pp, &
291 <            0.0E0_DP, 0.0E0_DP, 'N')
292 <       call eam_spline(number_r, EAMList%EAMParams(i)%eam_rvals, &
293 <            EAMList%EAMParams(i)%eam_phi_r, &
294 <            EAMList%EAMParams(i)%eam_phi_r_pp, &
295 <            0.0E0_DP, 0.0E0_DP, 'N')
296 <    enddo
297 <
298 <    !       current_rcut_max = EAMList%EAMParams(1)%eam_rcut
299 <    !! find the smallest rcut for any eam atype
300 <    !       do i = 2, EAMList%currentAddition
301 <    !          current_rcut_max =max(current_rcut_max,EAMList%EAMParams(i)%eam_rcut)
302 <    !       end do
303 <
304 <    !       EAM_rcut = current_rcut_max
305 <    !       EAM_rcut_orig = current_rcut_max
306 <    !       do i = 1, EAMList%currentAddition
307 <    !          EAMList%EAMParam(i)s%eam_atype_map(eam_atype(i)) = i
308 <    !       end do
238 >    
239      !! Allocate arrays for force calculation
240 <
311 <    call allocateEAM(alloc_stat)
312 <    if (alloc_stat /= 0 ) then
313 <       write(*,*) "allocateEAM failed"
314 <       status = -1
315 <       return
316 <    endif
317 <
318 <  end subroutine init_EAM_FF
319 <
320 <  !! routine checks to see if array is allocated, deallocates array if allocated
321 <  !! and then creates the array to the required size
322 <  subroutine allocateEAM(status)
323 <    integer, intent(out) :: status
324 <
325 < #ifdef IS_MPI
326 <    integer :: nAtomsInRow
327 <    integer :: nAtomsInCol
328 < #endif
329 <    integer :: alloc_stat
330 <
331 <
332 <    status = 0
240 >    
241   #ifdef IS_MPI
242      nAtomsInRow = getNatomsInRow(plan_atom_row)
243      nAtomsInCol = getNatomsInCol(plan_atom_col)
# Line 341 | Line 249 | contains
249         status = -1
250         return
251      end if
252 +
253      if (allocated(rho)) deallocate(rho)
254      allocate(rho(nlocal),stat=alloc_stat)
255      if (alloc_stat /= 0) then
# Line 355 | Line 264 | contains
264         return
265      end if
266  
358    if (allocated(d2frhodrhodrho)) deallocate(d2frhodrhodrho)
359    allocate(d2frhodrhodrho(nlocal),stat=alloc_stat)
360    if (alloc_stat /= 0) then
361       status = -1
362       return
363    end if
364
267   #ifdef IS_MPI
268  
269      if (allocated(rho_tmp)) deallocate(rho_tmp)
# Line 371 | Line 273 | contains
273         return
274      end if
275  
374
276      if (allocated(frho_row)) deallocate(frho_row)
277      allocate(frho_row(nAtomsInRow),stat=alloc_stat)
278      if (alloc_stat /= 0) then
# Line 390 | Line 291 | contains
291         status = -1
292         return
293      end if
393    if (allocated(d2frhodrhodrho_row)) deallocate(d2frhodrhodrho_row)
394    allocate(d2frhodrhodrho_row(nAtomsInRow),stat=alloc_stat)
395    if (alloc_stat /= 0) then
396       status = -1
397       return
398    end if
294  
400
295      ! Now do column arrays
296  
297      if (allocated(frho_col)) deallocate(frho_col)
# Line 418 | Line 312 | contains
312         status = -1
313         return
314      end if
421    if (allocated(d2frhodrhodrho_col)) deallocate(d2frhodrhodrho_col)
422    allocate(d2frhodrhodrho_col(nAtomsInCol),stat=alloc_stat)
423    if (alloc_stat /= 0) then
424       status = -1
425       return
426    end if
315  
316   #endif
317  
318 <  end subroutine allocateEAM
318 >  end subroutine init_EAM_FF
319  
320 <  !! C sets rcut to be the largest cutoff of any atype
433 <  !! present in this simulation. Doesn't include all atypes
434 <  !! sim knows about, just those in the simulation.
435 <  subroutine setCutoffEAM(rcut, status)
320 >  subroutine setCutoffEAM(rcut)
321      real(kind=dp) :: rcut
437    integer :: status
438    status = 0
439
322      EAM_rcut = rcut
441
323    end subroutine setCutoffEAM
324  
444
445
325    subroutine clean_EAM()
326  
327      ! clean non-IS_MPI first
# Line 461 | Line 340 | contains
340   #endif
341    end subroutine clean_EAM
342  
464
465
466  subroutine allocate_EAMType(eam_n_rho,eam_n_r,thisEAMType,stat)
467    integer, intent(in)          :: eam_n_rho
468    integer, intent(in)          :: eam_n_r
469    type (EAMType)               :: thisEAMType
470    integer, optional   :: stat
471    integer             :: alloc_stat
472
473
474
475    if (present(stat)) stat = 0
476
477    allocate(thisEAMType%eam_rvals(eam_n_r),stat=alloc_stat)  
478    if (alloc_stat /= 0 ) then
479       if (present(stat)) stat = -1
480       return
481    end if
482    allocate(thisEAMType%eam_rhovals(eam_n_rho),stat=alloc_stat)  
483    if (alloc_stat /= 0 ) then
484       if (present(stat)) stat = -1
485       return
486    end if
487    allocate(thisEAMType%eam_F_rho(eam_n_rho),stat=alloc_stat)  
488    if (alloc_stat /= 0 ) then
489       if (present(stat)) stat = -1
490       return
491    end if
492    allocate(thisEAMType%eam_Z_r(eam_n_r),stat=alloc_stat)        
493    if (alloc_stat /= 0 ) then
494       if (present(stat)) stat = -1
495       return
496    end if
497    allocate(thisEAMType%eam_rho_r(eam_n_r),stat=alloc_stat)      
498    if (alloc_stat /= 0 ) then
499       if (present(stat)) stat = -1
500       return
501    end if
502    allocate(thisEAMType%eam_phi_r(eam_n_r),stat=alloc_stat)      
503    if (alloc_stat /= 0 ) then
504       if (present(stat)) stat = -1
505       return
506    end if
507    allocate(thisEAMType%eam_F_rho_pp(eam_n_rho),stat=alloc_stat)  
508    if (alloc_stat /= 0 ) then
509       if (present(stat)) stat = -1
510       return
511    end if
512    allocate(thisEAMType%eam_Z_r_pp(eam_n_r),stat=alloc_stat)  
513    if (alloc_stat /= 0 ) then
514       if (present(stat)) stat = -1
515       return
516    end if
517    allocate(thisEAMType%eam_rho_r_pp(eam_n_r),stat=alloc_stat)  
518    if (alloc_stat /= 0 ) then
519       if (present(stat)) stat = -1
520       return
521    end if
522    allocate(thisEAMType%eam_phi_r_pp(eam_n_r),stat=alloc_stat)
523    if (alloc_stat /= 0 ) then
524       if (present(stat)) stat = -1
525       return
526    end if
527
528
529  end subroutine allocate_EAMType
530
531
343    subroutine deallocate_EAMType(thisEAMType)
344      type (EAMtype), pointer :: thisEAMType
345  
346 <    ! free Arrays in reverse order of allocation...
347 <    if(associated(thisEAMType%eam_phi_r_pp)) deallocate(thisEAMType%eam_phi_r_pp)      
348 <    if(associated(thisEAMType%eam_rho_r_pp)) deallocate(thisEAMType%eam_rho_r_pp)  
349 <    if(associated(thisEAMType%eam_Z_r_pp)) deallocate(thisEAMType%eam_Z_r_pp)  
539 <    if(associated(thisEAMType%eam_F_rho_pp)) deallocate(thisEAMType%eam_F_rho_pp)  
540 <    if(associated(thisEAMType%eam_phi_r)) deallocate(thisEAMType%eam_phi_r)      
541 <    if(associated(thisEAMType%eam_rho_r)) deallocate(thisEAMType%eam_rho_r)      
542 <    if(associated(thisEAMType%eam_Z_r)) deallocate(thisEAMType%eam_Z_r)  
543 <    if(associated(thisEAMType%eam_F_rho)) deallocate(thisEAMType%eam_F_rho)
544 <    if(associated(thisEAMType%eam_rhovals)) deallocate(thisEAMType%eam_rhovals)
545 <    if(associated(thisEAMType%eam_rvals)) deallocate(thisEAMType%eam_rvals)
346 >    call deleteSpline(thisEAMType%F)
347 >    call deleteSpline(thisEAMType%rho)
348 >    call deleteSpline(thisEAMType%phi)
349 >    call deleteSpline(thisEAMType%Z)
350  
351    end subroutine deallocate_EAMType
352  
353    !! Calculates rho_r
354    subroutine calc_eam_prepair_rho(atom1,atom2,d,r,rijsq)
355 <    integer :: atom1,atom2
355 >    integer :: atom1, atom2
356      real(kind = dp), dimension(3) :: d
357      real(kind = dp), intent(inout)               :: r
358      real(kind = dp), intent(inout)               :: rijsq
# Line 556 | Line 360 | contains
360      real(kind = dp) :: rho_i_at_j
361      ! value of electron density rho do to atom j at atom i
362      real(kind = dp) :: rho_j_at_i
559
560    ! we don't use the derivatives, dummy variables
561    real( kind = dp) :: drho,d2rho
363      integer :: eam_err
364 +    
365 +    integer :: atid1, atid2 ! Global atid    
366 +    integer :: myid_atom1 ! EAM atid
367 +    integer :: myid_atom2
368  
564    integer :: myid_atom1
565    integer :: myid_atom2
566
369      ! check to see if we need to be cleaned at the start of a force loop
370  
569
570
571
371   #ifdef IS_MPI
372 <    myid_atom1 = atid_Row(atom1)
373 <    myid_atom2 = atid_Col(atom2)
372 >    Atid1 = Atid_row(Atom1)
373 >    Atid2 = Atid_col(Atom2)
374   #else
375 <    myid_atom1 = atid(atom1)
376 <    myid_atom2 = atid(atom2)
375 >    Atid1 = Atid(Atom1)
376 >    Atid2 = Atid(Atom2)
377   #endif
378  
379 +    Myid_atom1 = Eamlist%atidtoeamtype(Atid1)
380 +    Myid_atom2 = Eamlist%atidtoeamtype(Atid2)
381 +
382      if (r.lt.EAMList%EAMParams(myid_atom1)%eam_rcut) then
383  
384 +       call lookupUniformSpline(EAMList%EAMParams(myid_atom1)%rho, r, &
385 +            rho_i_at_j)
386  
583
584       call eam_splint(EAMList%EAMParams(myid_atom1)%eam_nr, &
585            EAMList%EAMParams(myid_atom1)%eam_rvals, &
586            EAMList%EAMParams(myid_atom1)%eam_rho_r, &
587            EAMList%EAMParams(myid_atom1)%eam_rho_r_pp, &
588            r, rho_i_at_j,drho,d2rho)
589
590
591
387   #ifdef  IS_MPI
388         rho_col(atom2) = rho_col(atom2) + rho_i_at_j
389   #else
390         rho(atom2) = rho(atom2) + rho_i_at_j
391   #endif
597       !       write(*,*) atom1,atom2,r,rho_i_at_j
392      endif
393  
394      if (r.lt.EAMList%EAMParams(myid_atom2)%eam_rcut) then
601       call eam_splint(EAMList%EAMParams(myid_atom2)%eam_nr, &
602            EAMList%EAMParams(myid_atom2)%eam_rvals, &
603            EAMList%EAMParams(myid_atom2)%eam_rho_r, &
604            EAMList%EAMParams(myid_atom2)%eam_rho_r_pp, &
605            r, rho_j_at_i,drho,d2rho)
395  
396 +       call lookupUniformSpline(EAMList%EAMParams(myid_atom2)%rho, r, &
397 +            rho_j_at_i)
398  
608
609
399   #ifdef  IS_MPI
400         rho_row(atom1) = rho_row(atom1) + rho_j_at_i
401   #else
402         rho(atom1) = rho(atom1) + rho_j_at_i
403   #endif
404      endif
616
617
618
619
620
621
405    end subroutine calc_eam_prepair_rho
406  
407  
625
626
408    !! Calculate the functional F(rho) for all local atoms
409 <  subroutine calc_eam_preforce_Frho(nlocal,pot)
409 >  subroutine calc_eam_preforce_Frho(nlocal, pot)
410      integer :: nlocal
411      real(kind=dp) :: pot
412 <    integer :: i,j
412 >    integer :: i, j
413      integer :: atom
414 <    real(kind=dp) :: U,U1,U2
414 >    real(kind=dp) :: U,U1
415      integer :: atype1
416 <    integer :: me
636 <    integer :: n_rho_points
416 >    integer :: me, atid1
417  
638
418      cleanme = .true.
419 <    !! Scatter the electron density from  pre-pair calculation back to local atoms
419 >    !! Scatter the electron density from  pre-pair calculation back to
420 >    !! local atoms
421   #ifdef IS_MPI
422      call scatter(rho_row,rho,plan_atom_row,eam_err)
423      if (eam_err /= 0 ) then
# Line 653 | Line 433 | contains
433      rho(1:nlocal) = rho(1:nlocal) + rho_tmp(1:nlocal)
434   #endif
435  
656
657
436      !! Calculate F(rho) and derivative
437      do atom = 1, nlocal
438 <       me = atid(atom)
439 <       n_rho_points = EAMList%EAMParams(me)%eam_nrho
662 <       !  Check to see that the density is not greater than the larges rho we have calculated
663 <       if (rho(atom) < EAMList%EAMParams(me)%eam_rhovals(n_rho_points)) then
664 <          call eam_splint(n_rho_points, &
665 <               EAMList%EAMParams(me)%eam_rhovals, &
666 <               EAMList%EAMParams(me)%eam_f_rho, &
667 <               EAMList%EAMParams(me)%eam_f_rho_pp, &
668 <               rho(atom), & ! Actual Rho
669 <               u, u1, u2)
670 <       else
671 <          ! Calculate F(rho with the largest available rho value
672 <          call eam_splint(n_rho_points, &
673 <               EAMList%EAMParams(me)%eam_rhovals, &
674 <               EAMList%EAMParams(me)%eam_f_rho, &
675 <               EAMList%EAMParams(me)%eam_f_rho_pp, &
676 <               EAMList%EAMParams(me)%eam_rhovals(n_rho_points), & ! Largest rho
677 <               u,u1,u2)
678 <       end if
438 >       atid1 = atid(atom)
439 >       me = eamList%atidToEAMtype(atid1)
440  
441 <
441 >       call lookupUniformSpline1d(EAMList%EAMParams(me)%F, rho(atom), &
442 >            u, u1)
443 >      
444         frho(atom) = u
445         dfrhodrho(atom) = u1
683       d2frhodrhodrho(atom) = u2
446         pot = pot + u
447  
448      enddo
449  
688
689
450   #ifdef IS_MPI
451      !! communicate f(rho) and derivatives back into row and column arrays
452      call gather(frho,frho_row,plan_atom_row, eam_err)
# Line 705 | Line 465 | contains
465      if (eam_err /=  0) then
466         call handleError("cal_eam_forces()","MPI gather dfrhodrho_col failure")
467      endif
708
709
710
711
712
713    if (nmflag) then
714       call gather(d2frhodrhodrho,d2frhodrhodrho_row,plan_atom_row)
715       call gather(d2frhodrhodrho,d2frhodrhodrho_col,plan_atom_col)
716    endif
468   #endif
469  
470  
471    end subroutine calc_eam_preforce_Frho
472 <
722 <
723 <
724 <
472 >  
473    !! Does EAM pairwise Force calculation.  
474    subroutine do_eam_pair(atom1, atom2, d, rij, r2, sw, vpair, fpair, &
475         pot, f, do_pot)
# Line 735 | Line 483 | contains
483  
484      logical, intent(in) :: do_pot
485  
486 <    real( kind = dp ) :: drdx,drdy,drdz
487 <    real( kind = dp ) :: d2
488 <    real( kind = dp ) :: phab,pha,dvpdr,d2vpdrdr
489 <    real( kind = dp ) :: rha,drha,d2rha, dpha
742 <    real( kind = dp ) :: rhb,drhb,d2rhb, dphb
486 >    real( kind = dp ) :: drdx, drdy, drdz
487 >    real( kind = dp ) :: phab, pha, dvpdr
488 >    real( kind = dp ) :: rha, drha, dpha
489 >    real( kind = dp ) :: rhb, drhb, dphb
490      real( kind = dp ) :: dudr
491 <    real( kind = dp ) :: rci,rcj
492 <    real( kind = dp ) :: drhoidr,drhojdr
493 <    real( kind = dp ) :: d2rhoidrdr
494 <    real( kind = dp ) :: d2rhojdrdr
748 <    real( kind = dp ) :: Fx,Fy,Fz
749 <    real( kind = dp ) :: r,d2pha,phb,d2phb
491 >    real( kind = dp ) :: rci, rcj
492 >    real( kind = dp ) :: drhoidr, drhojdr
493 >    real( kind = dp ) :: Fx, Fy, Fz
494 >    real( kind = dp ) :: r, phb
495  
496 <    integer :: id1,id2
496 >    integer :: id1, id2
497      integer  :: mytype_atom1
498      integer  :: mytype_atom2
499 +    integer  :: atid1, atid2
500  
755    !Local Variables
756
757    ! write(*,*) "Frho: ", Frho(atom1)
758
501      phab = 0.0E0_DP
502      dvpdr = 0.0E0_DP
761    d2vpdrdr = 0.0E0_DP
503  
504      if (rij .lt. EAM_rcut) then
505  
506   #ifdef IS_MPI
507 <       mytype_atom1 = atid_row(atom1)
508 <       mytype_atom2 = atid_col(atom2)
507 >       atid1 = atid_row(atom1)
508 >       atid2 = atid_col(atom2)
509   #else
510 <       mytype_atom1 = atid(atom1)
511 <       mytype_atom2 = atid(atom2)
510 >       atid1 = atid(atom1)
511 >       atid2 = atid(atom2)
512   #endif
513 +
514 +       mytype_atom1 = EAMList%atidToEAMType(atid1)
515 +       mytype_atom2 = EAMList%atidTOEAMType(atid2)
516 +
517 +
518         ! get cutoff for atom 1
519         rci = EAMList%EAMParams(mytype_atom1)%eam_rcut
520         ! get type specific cutoff for atom 2
# Line 779 | Line 525 | contains
525         drdz = d(3)/rij
526  
527         if (rij.lt.rci) then
528 <          call eam_splint(EAMList%EAMParams(mytype_atom1)%eam_nr, &
529 <               EAMList%EAMParams(mytype_atom1)%eam_rvals, &
530 <               EAMList%EAMParams(mytype_atom1)%eam_rho_r, &
531 <               EAMList%EAMParams(mytype_atom1)%eam_rho_r_pp, &
532 <               rij, rha,drha,d2rha)
533 <          !! Calculate Phi(r) for atom1.
534 <          call eam_splint(EAMList%EAMParams(mytype_atom1)%eam_nr, &
535 <               EAMList%EAMParams(mytype_atom1)%eam_rvals, &
536 <               EAMList%EAMParams(mytype_atom1)%eam_phi_r, &
537 <               EAMList%EAMParams(mytype_atom1)%eam_phi_r_pp, &
538 <               rij, pha,dpha,d2pha)
528 >
529 >          ! Calculate rho and drho for atom1
530 >
531 >          call lookupUniformSpline1d(EAMList%EAMParams(mytype_atom1)%rho, &
532 >               rij, rha, drha)
533 >          
534 >          ! Calculate Phi(r) for atom1.
535 >          
536 >          call lookupUniformSpline1d(EAMList%EAMParams(mytype_atom1)%phi, &
537 >               rij, pha, dpha)
538 >
539         endif
540  
541         if (rij.lt.rcj) then      
796          ! Calculate rho,drho and d2rho for atom1
797          call eam_splint(EAMList%EAMParams(mytype_atom2)%eam_nr, &
798               EAMList%EAMParams(mytype_atom2)%eam_rvals, &
799               EAMList%EAMParams(mytype_atom2)%eam_rho_r, &
800               EAMList%EAMParams(mytype_atom2)%eam_rho_r_pp, &
801               rij, rhb,drhb,d2rhb)
542  
543 <          !! Calculate Phi(r) for atom2.
544 <          call eam_splint(EAMList%EAMParams(mytype_atom2)%eam_nr, &
545 <               EAMList%EAMParams(mytype_atom2)%eam_rvals, &
546 <               EAMList%EAMParams(mytype_atom2)%eam_phi_r, &
547 <               EAMList%EAMParams(mytype_atom2)%eam_phi_r_pp, &
548 <               rij, phb,dphb,d2phb)
543 >          ! Calculate rho and drho for atom2
544 >
545 >          call lookupUniformSpline1d(EAMList%EAMParams(mytype_atom2)%rho, &
546 >               rij, rhb, drhb)
547 >
548 >          ! Calculate Phi(r) for atom2.
549 >
550 >          call lookupUniformSpline1d(EAMList%EAMParams(mytype_atom2)%phi, &
551 >               rij, phb, dphb)
552 >
553         endif
554  
555         if (rij.lt.rci) then
556            phab = phab + 0.5E0_DP*(rhb/rha)*pha
557            dvpdr = dvpdr + 0.5E0_DP*((rhb/rha)*dpha + &
558                 pha*((drhb/rha) - (rhb*drha/rha/rha)))
815          d2vpdrdr = d2vpdrdr + 0.5E0_DP*((rhb/rha)*d2pha + &
816               2.0E0_DP*dpha*((drhb/rha) - (rhb*drha/rha/rha)) + &
817               pha*((d2rhb/rha) - 2.0E0_DP*(drhb*drha/rha/rha) + &
818               (2.0E0_DP*rhb*drha*drha/rha/rha/rha) - (rhb*d2rha/rha/rha)))
559         endif
560  
561         if (rij.lt.rcj) then
562            phab = phab + 0.5E0_DP*(rha/rhb)*phb
563            dvpdr = dvpdr + 0.5E0_DP*((rha/rhb)*dphb + &
564                 phb*((drha/rhb) - (rha*drhb/rhb/rhb)))
825          d2vpdrdr = d2vpdrdr + 0.5E0_DP*((rha/rhb)*d2phb + &
826               2.0E0_DP*dphb*((drha/rhb) - (rha*drhb/rhb/rhb)) + &
827               phb*((d2rha/rhb) - 2.0E0_DP*(drha*drhb/rhb/rhb) + &
828               (2.0E0_DP*rha*drhb*drhb/rhb/rhb/rhb) - (rha*d2rhb/rhb/rhb)))
565         endif
566  
567         drhoidr = drha
568         drhojdr = drhb
569  
834       d2rhoidrdr = d2rha
835       d2rhojdrdr = d2rhb
836
837
570   #ifdef IS_MPI
571         dudr = drhojdr*dfrhodrho_row(atom1)+drhoidr*dfrhodrho_col(atom2) &
572              + dvpdr
# Line 842 | Line 574 | contains
574   #else
575         dudr = drhojdr*dfrhodrho(atom1)+drhoidr*dfrhodrho(atom2) &
576              + dvpdr
845       ! write(*,*) "Atom1,Atom2, dfrhodrho(atom1) dfrhodrho(atom2): ", atom1,atom2,dfrhodrho(atom1),dfrhodrho(atom2)
577   #endif
578  
579         fx = dudr * drdx
# Line 852 | Line 583 | contains
583  
584   #ifdef IS_MPI
585         if (do_pot) then
586 <          pot_Row(atom1) = pot_Row(atom1) + phab*0.5
587 <          pot_Col(atom2) = pot_Col(atom2) + phab*0.5
586 >          pot_Row(METALLIC_POT,atom1) = pot_Row(METALLIC_POT,atom1) + phab*0.5
587 >          pot_Col(METALLIC_POT,atom2) = pot_Col(METALLIC_POT,atom2) + phab*0.5
588         end if
589  
590         f_Row(1,atom1) = f_Row(1,atom1) + fx
# Line 879 | Line 610 | contains
610   #endif
611  
612         vpair = vpair + phab
613 +
614   #ifdef IS_MPI
615         id1 = AtomRowToGlobal(atom1)
616         id2 = AtomColToGlobal(atom2)
# Line 894 | Line 626 | contains
626            fpair(3) = fpair(3) + fz
627  
628         endif
897
898       if (nmflag) then
899
900          drhoidr = drha
901          drhojdr = drhb
902          d2rhoidrdr = d2rha
903          d2rhojdrdr = d2rhb
904
905 #ifdef IS_MPI
906          d2 = d2vpdrdr + &
907               d2rhoidrdr*dfrhodrho_col(atom2) + &
908               d2rhojdrdr*dfrhodrho_row(atom1) + &
909               drhoidr*drhoidr*d2frhodrhodrho_col(atom2) + &
910               drhojdr*drhojdr*d2frhodrhodrho_row(atom1)
911
912 #else
913
914          d2 = d2vpdrdr + &
915               d2rhoidrdr*dfrhodrho(atom2) + &
916               d2rhojdrdr*dfrhodrho(atom1) + &
917               drhoidr*drhoidr*d2frhodrhodrho(atom2) + &
918               drhojdr*drhojdr*d2frhodrhodrho(atom1)
919 #endif
920       end if
921
629      endif
630    end subroutine do_eam_pair
631  
925
926  subroutine eam_splint(nx, xa, ya, yppa, x, y, dy, d2y)
927
928    integer :: atype, nx, j
929    real( kind = DP ), dimension(:) :: xa
930    real( kind = DP ), dimension(:) :: ya
931    real( kind = DP ), dimension(:) :: yppa
932    real( kind = DP ) :: x, y
933    real( kind = DP ) :: dy, d2y
934    real( kind = DP ) :: del, h, a, b, c, d
935    integer :: pp_arraySize
936
937
938    ! this spline code assumes that the x points are equally spaced
939    ! do not attempt to use this code if they are not.
940
941
942    ! find the closest point with a value below our own:
943    j = FLOOR(real((nx-1),kind=dp) * (x - xa(1)) / (xa(nx) - xa(1))) + 1
944
945    ! check to make sure we're inside the spline range:
946    if ((j.gt.nx).or.(j.lt.1)) then
947       write(errMSG,*) "EAM_splint: x is outside bounds of spline: ",x,j
948       call handleError(routineName,errMSG)
949    endif
950    ! check to make sure we haven't screwed up the calculation of j:
951    if ((x.lt.xa(j)).or.(x.gt.xa(j+1))) then
952       if (j.ne.nx) then
953          write(errMSG,*) "EAM_splint:",x," x is outside bounding range"
954          call handleError(routineName,errMSG)
955       endif
956    endif
957
958    del = xa(j+1) - x
959    h = xa(j+1) - xa(j)
960
961    a = del / h
962    b = 1.0E0_DP - a
963    c = a*(a*a - 1.0E0_DP)*h*h/6.0E0_DP
964    d = b*(b*b - 1.0E0_DP)*h*h/6.0E0_DP
965
966    y = a*ya(j) + b*ya(j+1) + c*yppa(j) + d*yppa(j+1)
967
968    dy = (ya(j+1)-ya(j))/h &
969         - (3.0E0_DP*a*a - 1.0E0_DP)*h*yppa(j)/6.0E0_DP &
970         + (3.0E0_DP*b*b - 1.0E0_DP)*h*yppa(j+1)/6.0E0_DP
971
972
973    d2y = a*yppa(j) + b*yppa(j+1)
974
975
976  end subroutine eam_splint
977
978
979  subroutine eam_spline(nx, xa, ya, yppa, yp1, ypn, boundary)
980
981
982    ! yp1 and ypn are the first derivatives of y at the two endpoints
983    ! if boundary is 'L' the lower derivative is used
984    ! if boundary is 'U' the upper derivative is used
985    ! if boundary is 'B' then both derivatives are used
986    ! if boundary is anything else, then both derivatives are assumed to be 0
987
988    integer :: nx, i, k, max_array_size
989
990    real( kind = DP ), dimension(:)        :: xa
991    real( kind = DP ), dimension(:)        :: ya
992    real( kind = DP ), dimension(:)        :: yppa
993    real( kind = DP ), dimension(size(xa)) :: u
994    real( kind = DP ) :: yp1,ypn,un,qn,sig,p
995    character(len=*) :: boundary
996
997    ! make sure the sizes match
998    if ((nx /= size(xa)) .or. (nx /= size(ya))) then
999       call handleWarning("EAM_SPLINE","Array size mismatch")
1000    end if
1001
1002    if ((boundary.eq.'l').or.(boundary.eq.'L').or. &
1003         (boundary.eq.'b').or.(boundary.eq.'B')) then
1004       yppa(1) = -0.5E0_DP
1005       u(1) = (3.0E0_DP/(xa(2)-xa(1)))*((ya(2)-&
1006            ya(1))/(xa(2)-xa(1))-yp1)
1007    else
1008       yppa(1) = 0.0E0_DP
1009       u(1)  = 0.0E0_DP
1010    endif
1011
1012    do i = 2, nx - 1
1013       sig = (xa(i) - xa(i-1)) / (xa(i+1) - xa(i-1))
1014       p = sig * yppa(i-1) + 2.0E0_DP
1015       yppa(i) = (sig - 1.0E0_DP) / p
1016       u(i) = (6.0E0_DP*((ya(i+1)-ya(i))/(xa(i+1)-xa(i)) - &
1017            (ya(i)-ya(i-1))/(xa(i)-xa(i-1)))/ &
1018            (xa(i+1)-xa(i-1)) - sig * u(i-1))/p
1019    enddo
1020
1021    if ((boundary.eq.'u').or.(boundary.eq.'U').or. &
1022         (boundary.eq.'b').or.(boundary.eq.'B')) then
1023       qn = 0.5E0_DP
1024       un = (3.0E0_DP/(xa(nx)-xa(nx-1)))* &
1025            (ypn-(ya(nx)-ya(nx-1))/(xa(nx)-xa(nx-1)))
1026    else
1027       qn = 0.0E0_DP
1028       un = 0.0E0_DP
1029    endif
1030
1031    yppa(nx)=(un-qn*u(nx-1))/(qn*yppa(nx-1)+1.0E0_DP)
1032
1033    do k = nx-1, 1, -1
1034       yppa(k)=yppa(k)*yppa(k+1)+u(k)
1035    enddo
1036
1037  end subroutine eam_spline
1038
632   end module eam

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines