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 1948 by gezelter, Fri Jan 14 20:31:16 2005 UTC vs.
Revision 2722 by gezelter, Thu Apr 20 18:24:24 2006 UTC

# Line 44 | Line 44 | module eam
44    use force_globals
45    use status
46    use atype_module
47 <  use Vector_class
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 63 | Line 66 | module eam
66  
67    character(len = 200) :: errMsg
68    character(len=*), parameter :: RoutineName =  "EAM MODULE"
69 < !! Logical that determines if eam arrays should be zeroed
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  
88 <
102 < !! Arrays for MPI storage
88 >  !! Arrays for MPI storage
89   #ifdef IS_MPI
90    real( kind = dp),save, dimension(:), allocatable :: dfrhodrho_col
91    real( kind = dp),save, dimension(:), allocatable :: dfrhodrho_row
# 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
100       integer           :: n_eam_types = 0
101       integer           :: currentAddition = 0
102 <    
102 >
103       type (EAMtype), pointer  :: EAMParams(:) => null()
104 +     integer, pointer         :: atidToEAMType(:) => null()
105    end type EAMTypeList
106  
122
107    type (eamTypeList), save :: EAMList
108  
109    !! standard eam stuff  
# Line 132 | Line 116 | module eam
116    public :: calc_eam_prepair_rho
117    public :: calc_eam_preforce_Frho
118    public :: clean_EAM
119 +  public :: destroyEAMTypes
120 +  public :: getEAMCut
121  
122   contains
123  
138
124    subroutine newEAMtype(lattice_constant,eam_nrho,eam_drho,eam_nr,&
125 <       eam_dr,rcut,eam_Z_r,eam_rho_r,eam_F_rho,&
141 <       eam_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
135 <    integer                                :: eam_ident
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
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  
162
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.
165  
148  
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., nAtypes, MatchList)
152 <       EAMList%n_eam_types = nAtypes
153 <       allocate(EAMList%EAMParams(nAtypes))
151 >       call getMatchingElementList(atypes, "is_EAM", .true., nEAMtypes, MatchList)
152 >       EAMList%n_eam_types = nEAMtypes
153 >       allocate(EAMList%EAMParams(nEAMTypes))
154 >       nAtypes = getSize(atypes)
155 >       allocate(EAMList%atidToEAMType(nAtypes))
156      end if
157  
158      EAMList%currentAddition = EAMList%currentAddition + 1
159      current = EAMList%currentAddition
176    
160  
161 <    call allocate_EAMType(eam_nrho,eam_nr,EAMList%EAMParams(current),stat=alloc_stat)
162 <    if (alloc_stat /= 0) then
180 <       status = -1
181 <       return
182 <    end if
161 >    myATID =  getFirstMatchingElement(atypes, "c_ident", c_ident)
162 >    EAMList%atidToEAMType(myATID) = current
163  
164 <    ! this is a possible bug, we assume a correspondence between the vector atypes and
185 <    ! EAMAtypes
186 <      
187 <    EAMList%EAMParams(current)%eam_atype    = eam_ident
164 >    EAMList%EAMParams(current)%eam_atype    = c_ident
165      EAMList%EAMParams(current)%eam_lattice  = lattice_constant
189    EAMList%EAMParams(current)%eam_nrho     = eam_nrho
190    EAMList%EAMParams(current)%eam_drho     = eam_drho
191    EAMList%EAMParams(current)%eam_nr       = eam_nr
192    EAMList%EAMParams(current)%eam_dr       = eam_dr
166      EAMList%EAMParams(current)%eam_rcut     = rcut
194    EAMList%EAMParams(current)%eam_Z_r      = eam_Z_r
195    EAMList%EAMParams(current)%eam_rho_r    = eam_rho_r
196    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  
196 +  ! kills all eam types entered and sets simulation to uninitalized
197 +  subroutine destroyEAMtypes()
198 +    integer :: i
199 +    type(EAMType), pointer :: tempEAMType=>null()
200  
201 +    do i = 1, EAMList%n_eam_types
202 +       tempEAMType => eamList%EAMParams(i)
203 +       call deallocate_EAMType(tempEAMType)
204 +    end do
205 +    if(associated( eamList%EAMParams)) deallocate( eamList%EAMParams)
206 +    eamList%EAMParams => null()
207 +
208 +    eamList%n_eam_types = 0
209 +    eamList%currentAddition = 0
210 +  end subroutine destroyEAMtypes
211 +
212 +  function getEAMCut(atomID) result(cutValue)
213 +    integer, intent(in) :: atomID
214 +    integer :: eamID
215 +    real(kind=dp) :: cutValue
216 +    
217 +    eamID = EAMList%atidToEAMType(atomID)
218 +    cutValue = EAMList%EAMParams(eamID)%eam_rcut
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  
209
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 <
239 <
218 <       do i = 1, EAMList%currentAddition
219 <
220 < ! Build array of r values
221 <
222 <          do j = 1,EAMList%EAMParams(i)%eam_nr
223 <             EAMList%EAMParams(i)%eam_rvals(j) = &
224 <                  real(j-1,kind=dp)* &
225 <                  EAMList%EAMParams(i)%eam_dr
226 <              end do
227 < ! Build array of rho values
228 <          do j = 1,EAMList%EAMParams(i)%eam_nrho
229 <             EAMList%EAMParams(i)%eam_rhovals(j) = &
230 <                  real(j-1,kind=dp)* &
231 <                  EAMList%EAMParams(i)%eam_drho
232 <          end do
233 <          ! convert from eV to kcal / mol:
234 <          EAMList%EAMParams(i)%eam_F_rho = EAMList%EAMParams(i)%eam_F_rho * 23.06054E0_DP
235 <
236 <          ! precompute the pair potential and get it into kcal / mol:
237 <          EAMList%EAMParams(i)%eam_phi_r(1) = 0.0E0_DP
238 <          do j = 2, EAMList%EAMParams(i)%eam_nr
239 <             EAMList%EAMParams(i)%eam_phi_r(j) = (EAMList%EAMParams(i)%eam_Z_r(j)**2)/EAMList%EAMParams(i)%eam_rvals(j)
240 <             EAMList%EAMParams(i)%eam_phi_r(j) =  EAMList%EAMParams(i)%eam_phi_r(j)*331.999296E0_DP
241 <          enddo
242 <       end do
243 <      
244 <
245 <       do i = 1,  EAMList%currentAddition
246 <          number_r   = EAMList%EAMParams(i)%eam_nr
247 <          number_rho = EAMList%EAMParams(i)%eam_nrho
248 <          
249 <          call eam_spline(number_r, EAMList%EAMParams(i)%eam_rvals, &
250 <               EAMList%EAMParams(i)%eam_rho_r, &
251 <               EAMList%EAMParams(i)%eam_rho_r_pp, &
252 <               0.0E0_DP, 0.0E0_DP, 'N')
253 <          call eam_spline(number_r, EAMList%EAMParams(i)%eam_rvals, &
254 <               EAMList%EAMParams(i)%eam_Z_r, &
255 <               EAMList%EAMParams(i)%eam_Z_r_pp, &
256 <               0.0E0_DP, 0.0E0_DP, 'N')
257 <          call eam_spline(number_rho, EAMList%EAMParams(i)%eam_rhovals, &
258 <               EAMList%EAMParams(i)%eam_F_rho, &
259 <               EAMList%EAMParams(i)%eam_F_rho_pp, &
260 <               0.0E0_DP, 0.0E0_DP, 'N')
261 <          call eam_spline(number_r, EAMList%EAMParams(i)%eam_rvals, &
262 <               EAMList%EAMParams(i)%eam_phi_r, &
263 <               EAMList%EAMParams(i)%eam_phi_r_pp, &
264 <               0.0E0_DP, 0.0E0_DP, 'N')
265 <       enddo
266 <
267 < !       current_rcut_max = EAMList%EAMParams(1)%eam_rcut
268 <       !! find the smallest rcut for any eam atype
269 < !       do i = 2, EAMList%currentAddition
270 < !          current_rcut_max =max(current_rcut_max,EAMList%EAMParams(i)%eam_rcut)
271 < !       end do
272 <
273 < !       EAM_rcut = current_rcut_max
274 < !       EAM_rcut_orig = current_rcut_max
275 < !       do i = 1, EAMList%currentAddition
276 < !          EAMList%EAMParam(i)s%eam_atype_map(eam_atype(i)) = i
277 < !       end do
278 <       !! Allocate arrays for force calculation
279 <      
280 <       call allocateEAM(alloc_stat)
281 <       if (alloc_stat /= 0 ) then
282 <          write(*,*) "allocateEAM failed"
283 <          status = -1
284 <          return
285 <       endif
238 >    
239 >    !! Allocate arrays for force calculation
240      
287  end subroutine init_EAM_FF
288
289 !! routine checks to see if array is allocated, deallocates array if allocated
290 !! and then creates the array to the required size
291  subroutine allocateEAM(status)
292    integer, intent(out) :: status
293
241   #ifdef IS_MPI
295    integer :: nAtomsInRow
296    integer :: nAtomsInCol
297 #endif
298    integer :: alloc_stat
299
300
301    status = 0
302 #ifdef IS_MPI
242      nAtomsInRow = getNatomsInRow(plan_atom_row)
243      nAtomsInCol = getNatomsInCol(plan_atom_col)
244   #endif
# Line 310 | 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 324 | Line 264 | contains
264         return
265      end if
266  
327    if (allocated(d2frhodrhodrho)) deallocate(d2frhodrhodrho)
328    allocate(d2frhodrhodrho(nlocal),stat=alloc_stat)
329    if (alloc_stat /= 0) then
330       status = -1
331       return
332    end if
333    
267   #ifdef IS_MPI
268  
269      if (allocated(rho_tmp)) deallocate(rho_tmp)
# Line 340 | Line 273 | contains
273         return
274      end if
275  
343
276      if (allocated(frho_row)) deallocate(frho_row)
277      allocate(frho_row(nAtomsInRow),stat=alloc_stat)
278      if (alloc_stat /= 0) then
# Line 359 | Line 291 | contains
291         status = -1
292         return
293      end if
362    if (allocated(d2frhodrhodrho_row)) deallocate(d2frhodrhodrho_row)
363    allocate(d2frhodrhodrho_row(nAtomsInRow),stat=alloc_stat)
364    if (alloc_stat /= 0) then
365       status = -1
366       return
367    end if
294  
295 +    ! Now do column arrays
296  
370 ! Now do column arrays
371
297      if (allocated(frho_col)) deallocate(frho_col)
298      allocate(frho_col(nAtomsInCol),stat=alloc_stat)
299      if (alloc_stat /= 0) then
# Line 387 | Line 312 | contains
312         status = -1
313         return
314      end if
315 <    if (allocated(d2frhodrhodrho_col)) deallocate(d2frhodrhodrho_col)
391 <    allocate(d2frhodrhodrho_col(nAtomsInCol),stat=alloc_stat)
392 <    if (alloc_stat /= 0) then
393 <       status = -1
394 <       return
395 <    end if
396 <  
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
402 < !! present in this simulation. Doesn't include all atypes
403 < !! sim knows about, just those in the simulation.
404 <  subroutine setCutoffEAM(rcut, status)
320 >  subroutine setCutoffEAM(rcut)
321      real(kind=dp) :: rcut
406    integer :: status
407    status = 0
408
322      EAM_rcut = rcut
410
323    end subroutine setCutoffEAM
324  
413
414
325    subroutine clean_EAM()
326 <  
327 <   ! clean non-IS_MPI first
326 >
327 >    ! clean non-IS_MPI first
328      frho = 0.0_dp
329      rho  = 0.0_dp
330      dfrhodrho = 0.0_dp
331 < ! clean MPI if needed
331 >    ! clean MPI if needed
332   #ifdef IS_MPI
333      frho_row = 0.0_dp
334      frho_col = 0.0_dp
# Line 430 | Line 340 | contains
340   #endif
341    end subroutine clean_EAM
342  
433
434
435  subroutine allocate_EAMType(eam_n_rho,eam_n_r,thisEAMType,stat)
436    integer, intent(in)          :: eam_n_rho
437    integer, intent(in)          :: eam_n_r
438    type (EAMType)               :: thisEAMType
439    integer, optional   :: stat
440    integer             :: alloc_stat
441
442
443
444    if (present(stat)) stat = 0
445    
446    allocate(thisEAMType%eam_rvals(eam_n_r),stat=alloc_stat)  
447    if (alloc_stat /= 0 ) then
448       if (present(stat)) stat = -1
449       return
450    end if
451    allocate(thisEAMType%eam_rhovals(eam_n_rho),stat=alloc_stat)  
452    if (alloc_stat /= 0 ) then
453       if (present(stat)) stat = -1
454       return
455    end if
456    allocate(thisEAMType%eam_F_rho(eam_n_rho),stat=alloc_stat)  
457    if (alloc_stat /= 0 ) then
458       if (present(stat)) stat = -1
459       return
460    end if
461    allocate(thisEAMType%eam_Z_r(eam_n_r),stat=alloc_stat)        
462    if (alloc_stat /= 0 ) then
463       if (present(stat)) stat = -1
464       return
465    end if
466    allocate(thisEAMType%eam_rho_r(eam_n_r),stat=alloc_stat)      
467    if (alloc_stat /= 0 ) then
468       if (present(stat)) stat = -1
469       return
470    end if
471    allocate(thisEAMType%eam_phi_r(eam_n_r),stat=alloc_stat)      
472    if (alloc_stat /= 0 ) then
473       if (present(stat)) stat = -1
474       return
475    end if
476    allocate(thisEAMType%eam_F_rho_pp(eam_n_rho),stat=alloc_stat)  
477    if (alloc_stat /= 0 ) then
478       if (present(stat)) stat = -1
479       return
480    end if
481    allocate(thisEAMType%eam_Z_r_pp(eam_n_r),stat=alloc_stat)  
482    if (alloc_stat /= 0 ) then
483       if (present(stat)) stat = -1
484       return
485    end if
486    allocate(thisEAMType%eam_rho_r_pp(eam_n_r),stat=alloc_stat)  
487    if (alloc_stat /= 0 ) then
488       if (present(stat)) stat = -1
489       return
490    end if
491    allocate(thisEAMType%eam_phi_r_pp(eam_n_r),stat=alloc_stat)
492    if (alloc_stat /= 0 ) then
493       if (present(stat)) stat = -1
494       return
495    end if
496      
497
498  end subroutine allocate_EAMType
499
500
343    subroutine deallocate_EAMType(thisEAMType)
344      type (EAMtype), pointer :: thisEAMType
345  
346 <    ! free Arrays in reverse order of allocation...
347 <    deallocate(thisEAMType%eam_phi_r_pp)      
348 <    deallocate(thisEAMType%eam_rho_r_pp)  
349 <    deallocate(thisEAMType%eam_Z_r_pp)  
350 <    deallocate(thisEAMType%eam_F_rho_pp)  
509 <    deallocate(thisEAMType%eam_phi_r)      
510 <    deallocate(thisEAMType%eam_rho_r)      
511 <    deallocate(thisEAMType%eam_Z_r)  
512 <    deallocate(thisEAMType%eam_F_rho)
513 <    deallocate(thisEAMType%eam_rhovals)
514 <    deallocate(thisEAMType%eam_rvals)
515 <  
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
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 525 | 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
528
529    ! we don't use the derivatives, dummy variables
530    real( kind = dp) :: drho,d2rho
363      integer :: eam_err
364 <  
365 <    integer :: myid_atom1
366 <    integer :: myid_atom2
364 >    
365 >    integer :: atid1, atid2 ! Global atid    
366 >    integer :: myid_atom1 ! EAM atid
367 >    integer :: myid_atom2
368  
369 < ! check to see if we need to be cleaned at the start of a force loop
537 <      
369 >    ! check to see if we need to be cleaned at the start of a force loop
370  
539
540
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  
552
553       call eam_splint(EAMList%EAMParams(myid_atom1)%eam_nr, &
554            EAMList%EAMParams(myid_atom1)%eam_rvals, &
555            EAMList%EAMParams(myid_atom1)%eam_rho_r, &
556            EAMList%EAMParams(myid_atom1)%eam_rho_r_pp, &
557            r, rho_i_at_j,drho,d2rho)
558
559
560      
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
392 < !       write(*,*) atom1,atom2,r,rho_i_at_j
567 <       endif
392 >    endif
393  
394 <       if (r.lt.EAMList%EAMParams(myid_atom2)%eam_rcut) then
570 <          call eam_splint(EAMList%EAMParams(myid_atom2)%eam_nr, &
571 <               EAMList%EAMParams(myid_atom2)%eam_rvals, &
572 <               EAMList%EAMParams(myid_atom2)%eam_rho_r, &
573 <               EAMList%EAMParams(myid_atom2)%eam_rho_r_pp, &
574 <               r, rho_j_at_i,drho,d2rho)
394 >    if (r.lt.EAMList%EAMParams(myid_atom2)%eam_rcut) then
395  
396 <    
397 <      
398 <      
396 >       call lookupUniformSpline(EAMList%EAMParams(myid_atom2)%rho, r, &
397 >            rho_j_at_i)
398 >
399   #ifdef  IS_MPI
400 <          rho_row(atom1) = rho_row(atom1) + rho_j_at_i
400 >       rho_row(atom1) = rho_row(atom1) + rho_j_at_i
401   #else
402 <          rho(atom1) = rho(atom1) + rho_j_at_i
402 >       rho(atom1) = rho(atom1) + rho_j_at_i
403   #endif
404 <       endif
585 <
586 <
587 <
588 <
589 <
590 <
404 >    endif
405    end subroutine calc_eam_prepair_rho
406  
407  
594
595
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
605 <    integer :: n_rho_points
416 >    integer :: me, atid1
417  
607  
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
424 <      write(errMsg,*) " Error scattering rho_row into rho"
425 <      call handleError(RoutineName,errMesg)
426 <   endif      
424 >       write(errMsg,*) " Error scattering rho_row into rho"
425 >       call handleError(RoutineName,errMesg)
426 >    endif
427      call scatter(rho_col,rho_tmp,plan_atom_col,eam_err)
428      if (eam_err /= 0 ) then
429 <      write(errMsg,*) " Error scattering rho_col into rho"
430 <      call handleError(RoutineName,errMesg)
431 <   endif
429 >       write(errMsg,*) " Error scattering rho_col into rho"
430 >       call handleError(RoutineName,errMesg)
431 >    endif
432  
433 <      rho(1:nlocal) = rho(1:nlocal) + rho_tmp(1:nlocal)
433 >    rho(1:nlocal) = rho(1:nlocal) + rho_tmp(1:nlocal)
434   #endif
435  
436 <
626 <
627 < !! Calculate F(rho) and derivative
436 >    !! Calculate F(rho) and derivative
437      do atom = 1, nlocal
438 <       me = atid(atom)
439 <       n_rho_points = EAMList%EAMParams(me)%eam_nrho
631 <       !  Check to see that the density is not greater than the larges rho we have calculated
632 <       if (rho(atom) < EAMList%EAMParams(me)%eam_rhovals(n_rho_points)) then
633 <          call eam_splint(n_rho_points, &
634 <               EAMList%EAMParams(me)%eam_rhovals, &
635 <               EAMList%EAMParams(me)%eam_f_rho, &
636 <               EAMList%EAMParams(me)%eam_f_rho_pp, &
637 <               rho(atom), & ! Actual Rho
638 <               u, u1, u2)
639 <       else
640 <          ! Calculate F(rho with the largest available rho value
641 <          call eam_splint(n_rho_points, &
642 <               EAMList%EAMParams(me)%eam_rhovals, &
643 <               EAMList%EAMParams(me)%eam_f_rho, &
644 <               EAMList%EAMParams(me)%eam_f_rho_pp, &
645 <               EAMList%EAMParams(me)%eam_rhovals(n_rho_points), & ! Largest rho
646 <               u,u1,u2)
647 <       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
652       d2frhodrhodrho(atom) = u2
446         pot = pot + u
447  
448      enddo
449  
657  
658
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 674 | Line 465 | contains
465      if (eam_err /=  0) then
466         call handleError("cal_eam_forces()","MPI gather dfrhodrho_col failure")
467      endif
677
678
679
680
681
682    if (nmflag) then
683       call gather(d2frhodrhodrho,d2frhodrhodrho_row,plan_atom_row)
684       call gather(d2frhodrhodrho,d2frhodrhodrho_col,plan_atom_col)
685    endif
468   #endif
469  
688  
689  end subroutine calc_eam_preforce_Frho
470  
471 <
472 <
693 <
471 >  end subroutine calc_eam_preforce_Frho
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 703 | Line 482 | contains
482      real( kind = dp ), intent(inout), dimension(3) :: fpair
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
711 <    real( kind = dp ) :: rhb,drhb,d2rhb, dphb
485 >
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
717 <    real( kind = dp ) :: Fx,Fy,Fz
718 <    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  
724 !Local Variables
725    
726   ! write(*,*) "Frho: ", Frho(atom1)
727
501      phab = 0.0E0_DP
502      dvpdr = 0.0E0_DP
730    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
521         rcj = EAMList%EAMParams(mytype_atom2)%eam_rcut
522 <      
522 >
523         drdx = d(1)/rij
524         drdy = d(2)/rij
525         drdz = d(3)/rij
526 <      
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      
542 <          ! Calculate rho,drho and d2rho for atom1
543 <          call eam_splint(EAMList%EAMParams(mytype_atom2)%eam_nr, &
544 <               EAMList%EAMParams(mytype_atom2)%eam_rvals, &
545 <               EAMList%EAMParams(mytype_atom2)%eam_rho_r, &
546 <               EAMList%EAMParams(mytype_atom2)%eam_rho_r_pp, &
547 <               rij, rhb,drhb,d2rhb)
548 <          
549 <          !! Calculate Phi(r) for atom2.
550 <          call eam_splint(EAMList%EAMParams(mytype_atom2)%eam_nr, &
551 <               EAMList%EAMParams(mytype_atom2)%eam_rvals, &
552 <               EAMList%EAMParams(mytype_atom2)%eam_phi_r, &
776 <               EAMList%EAMParams(mytype_atom2)%eam_phi_r_pp, &
777 <               rij, phb,dphb,d2phb)
542 >
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)))
784          d2vpdrdr = d2vpdrdr + 0.5E0_DP*((rhb/rha)*d2pha + &
785               2.0E0_DP*dpha*((drhb/rha) - (rhb*drha/rha/rha)) + &
786               pha*((d2rhb/rha) - 2.0E0_DP*(drhb*drha/rha/rha) + &
787               (2.0E0_DP*rhb*drha*drha/rha/rha/rha) - (rhb*d2rha/rha/rha)))
559         endif
560 <      
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)))
794          d2vpdrdr = d2vpdrdr + 0.5E0_DP*((rha/rhb)*d2phb + &
795               2.0E0_DP*dphb*((drha/rhb) - (rha*drhb/rhb/rhb)) + &
796               phb*((d2rha/rhb) - 2.0E0_DP*(drha*drhb/rhb/rhb) + &
797               (2.0E0_DP*rha*drhb*drhb/rhb/rhb/rhb) - (rha*d2rhb/rhb/rhb)))
565         endif
566 <      
566 >
567         drhoidr = drha
568         drhojdr = drhb
569  
803       d2rhoidrdr = d2rha
804       d2rhojdrdr = d2rhb
805
806
570   #ifdef IS_MPI
571         dudr = drhojdr*dfrhodrho_row(atom1)+drhoidr*dfrhodrho_col(atom2) &
572              + dvpdr
# Line 811 | Line 574 | contains
574   #else
575         dudr = drhojdr*dfrhodrho(atom1)+drhoidr*dfrhodrho(atom2) &
576              + dvpdr
814      ! write(*,*) "Atom1,Atom2, dfrhodrho(atom1) dfrhodrho(atom2): ", atom1,atom2,dfrhodrho(atom1),dfrhodrho(atom2)
577   #endif
578  
579         fx = dudr * drdx
# Line 821 | 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
591         f_Row(2,atom1) = f_Row(2,atom1) + fy
592         f_Row(3,atom1) = f_Row(3,atom1) + fz
593 <      
593 >
594         f_Col(1,atom2) = f_Col(1,atom2) - fx
595         f_Col(2,atom2) = f_Col(2,atom2) - fy
596         f_Col(3,atom2) = f_Col(3,atom2) - fz
# Line 841 | Line 603 | contains
603         f(1,atom1) = f(1,atom1) + fx
604         f(2,atom1) = f(2,atom1) + fy
605         f(3,atom1) = f(3,atom1) + fz
606 <      
606 >
607         f(1,atom2) = f(1,atom2) - fx
608         f(2,atom2) = f(2,atom2) - fy
609         f(3,atom2) = f(3,atom2) - fz
610   #endif
611 <      
611 >
612         vpair = vpair + phab
613 +
614   #ifdef IS_MPI
615         id1 = AtomRowToGlobal(atom1)
616         id2 = AtomColToGlobal(atom2)
# Line 855 | Line 618 | contains
618         id1 = atom1
619         id2 = atom2
620   #endif
621 <      
621 >
622         if (molMembershipList(id1) .ne. molMembershipList(id2)) then
623 <          
623 >
624            fpair(1) = fpair(1) + fx
625            fpair(2) = fpair(2) + fy
626            fpair(3) = fpair(3) + fz
864          
865       endif
866    
867       if (nmflag) then
627  
869          drhoidr = drha
870          drhojdr = drhb
871          d2rhoidrdr = d2rha
872          d2rhojdrdr = d2rhb
873
874 #ifdef IS_MPI
875          d2 = d2vpdrdr + &
876               d2rhoidrdr*dfrhodrho_col(atom2) + &
877               d2rhojdrdr*dfrhodrho_row(atom1) + &
878               drhoidr*drhoidr*d2frhodrhodrho_col(atom2) + &
879               drhojdr*drhojdr*d2frhodrhodrho_row(atom1)
880              
881 #else
882
883          d2 = d2vpdrdr + &
884               d2rhoidrdr*dfrhodrho(atom2) + &
885               d2rhojdrdr*dfrhodrho(atom1) + &
886               drhoidr*drhoidr*d2frhodrhodrho(atom2) + &
887               drhojdr*drhojdr*d2frhodrhodrho(atom1)
888 #endif
889       end if
890      
891    endif    
892  end subroutine do_eam_pair
893
894
895  subroutine eam_splint(nx, xa, ya, yppa, x, y, dy, d2y)
896
897    integer :: atype, nx, j
898    real( kind = DP ), dimension(:) :: xa
899    real( kind = DP ), dimension(:) :: ya
900    real( kind = DP ), dimension(:) :: yppa
901    real( kind = DP ) :: x, y
902    real( kind = DP ) :: dy, d2y
903    real( kind = DP ) :: del, h, a, b, c, d
904    integer :: pp_arraySize
905
906
907    ! this spline code assumes that the x points are equally spaced
908    ! do not attempt to use this code if they are not.
909    
910    
911    ! find the closest point with a value below our own:
912    j = FLOOR(real((nx-1),kind=dp) * (x - xa(1)) / (xa(nx) - xa(1))) + 1
913
914    ! check to make sure we're inside the spline range:
915    if ((j.gt.nx).or.(j.lt.1)) then
916       write(errMSG,*) "EAM_splint: x is outside bounds of spline: ",x,j
917       call handleError(routineName,errMSG)
918    endif
919    ! check to make sure we haven't screwed up the calculation of j:
920    if ((x.lt.xa(j)).or.(x.gt.xa(j+1))) then
921       if (j.ne.nx) then
922        write(errMSG,*) "EAM_splint:",x," x is outside bounding range"
923       call handleError(routineName,errMSG)
628         endif
629      endif
630 +  end subroutine do_eam_pair
631  
927    del = xa(j+1) - x
928    h = xa(j+1) - xa(j)
929    
930    a = del / h
931    b = 1.0E0_DP - a
932    c = a*(a*a - 1.0E0_DP)*h*h/6.0E0_DP
933    d = b*(b*b - 1.0E0_DP)*h*h/6.0E0_DP
934    
935    y = a*ya(j) + b*ya(j+1) + c*yppa(j) + d*yppa(j+1)
936  
937       dy = (ya(j+1)-ya(j))/h &
938            - (3.0E0_DP*a*a - 1.0E0_DP)*h*yppa(j)/6.0E0_DP &
939            + (3.0E0_DP*b*b - 1.0E0_DP)*h*yppa(j+1)/6.0E0_DP
940  
941  
942       d2y = a*yppa(j) + b*yppa(j+1)
943  
944
945  end subroutine eam_splint
946
947
948  subroutine eam_spline(nx, xa, ya, yppa, yp1, ypn, boundary)
949
950
951    ! yp1 and ypn are the first derivatives of y at the two endpoints
952    ! if boundary is 'L' the lower derivative is used
953    ! if boundary is 'U' the upper derivative is used
954    ! if boundary is 'B' then both derivatives are used
955    ! if boundary is anything else, then both derivatives are assumed to be 0
956    
957    integer :: nx, i, k, max_array_size
958    
959    real( kind = DP ), dimension(:)        :: xa
960    real( kind = DP ), dimension(:)        :: ya
961    real( kind = DP ), dimension(:)        :: yppa
962    real( kind = DP ), dimension(size(xa)) :: u
963    real( kind = DP ) :: yp1,ypn,un,qn,sig,p
964    character(len=*) :: boundary
965    
966    ! make sure the sizes match
967    if ((nx /= size(xa)) .or. (nx /= size(ya))) then
968       call handleWarning("EAM_SPLINE","Array size mismatch")
969    end if
970
971    if ((boundary.eq.'l').or.(boundary.eq.'L').or. &
972         (boundary.eq.'b').or.(boundary.eq.'B')) then
973       yppa(1) = -0.5E0_DP
974       u(1) = (3.0E0_DP/(xa(2)-xa(1)))*((ya(2)-&
975            ya(1))/(xa(2)-xa(1))-yp1)
976    else
977       yppa(1) = 0.0E0_DP
978       u(1)  = 0.0E0_DP
979    endif
980    
981    do i = 2, nx - 1
982       sig = (xa(i) - xa(i-1)) / (xa(i+1) - xa(i-1))
983       p = sig * yppa(i-1) + 2.0E0_DP
984       yppa(i) = (sig - 1.0E0_DP) / p
985       u(i) = (6.0E0_DP*((ya(i+1)-ya(i))/(xa(i+1)-xa(i)) - &
986            (ya(i)-ya(i-1))/(xa(i)-xa(i-1)))/ &
987            (xa(i+1)-xa(i-1)) - sig * u(i-1))/p
988    enddo
989    
990    if ((boundary.eq.'u').or.(boundary.eq.'U').or. &
991         (boundary.eq.'b').or.(boundary.eq.'B')) then
992       qn = 0.5E0_DP
993       un = (3.0E0_DP/(xa(nx)-xa(nx-1)))* &
994            (ypn-(ya(nx)-ya(nx-1))/(xa(nx)-xa(nx-1)))
995    else
996       qn = 0.0E0_DP
997       un = 0.0E0_DP
998    endif
999
1000    yppa(nx)=(un-qn*u(nx-1))/(qn*yppa(nx-1)+1.0E0_DP)
1001    
1002    do k = nx-1, 1, -1
1003       yppa(k)=yppa(k)*yppa(k+1)+u(k)
1004    enddo
1005
1006  end subroutine eam_spline
1007
632   end module eam

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines