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 2717 by gezelter, Mon Apr 17 21:49:12 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
167 <    EAMList%EAMParams(current)%eam_Z_r      = eam_Z_r
168 <    EAMList%EAMParams(current)%eam_rho_r    = eam_rho_r
169 <    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, rhovals, &
190 +         0.0d0, 0.0d0, .true.)
191 +    call newSpline(EAMList%EAMParams(current)%Z,   rvals, eam_Z_r, &
192 +         0.0d0, 0.0d0, .true.)
193 +    call newSpline(EAMList%EAMParams(current)%F, rhovals, eam_F_rho, &
194 +         0.0d0, 0.0d0, .true.)
195 +    call newSpline(EAMList%EAMParams(current)%phi, rvals, eam_phi_r, &
196 +         0.0d0, 0.0d0, .true.)
197    end subroutine newEAMtype
198  
199  
200 +  ! kills all eam types entered and sets simulation to uninitalized
201 +  subroutine destroyEAMtypes()
202 +    integer :: i
203 +    type(EAMType), pointer :: tempEAMType=>null()
204  
205 +    do i = 1, EAMList%n_eam_types
206 +       tempEAMType => eamList%EAMParams(i)
207 +       call deallocate_EAMType(tempEAMType)
208 +    end do
209 +    if(associated( eamList%EAMParams)) deallocate( eamList%EAMParams)
210 +    eamList%EAMParams => null()
211 +
212 +    eamList%n_eam_types = 0
213 +    eamList%currentAddition = 0
214 +  end subroutine destroyEAMtypes
215 +
216 +  function getEAMCut(atomID) result(cutValue)
217 +    integer, intent(in) :: atomID
218 +    integer :: eamID
219 +    real(kind=dp) :: cutValue
220 +    
221 +    eamID = EAMList%atidToEAMType(atomID)
222 +    cutValue = EAMList%EAMParams(eamID)%eam_rcut
223 +  end function getEAMCut
224 +
225    subroutine init_EAM_FF(status)
226      integer :: status
227      integer :: i,j
228      real(kind=dp) :: current_rcut_max
229 + #ifdef IS_MPI
230 +    integer :: nAtomsInRow
231 +    integer :: nAtomsInCol
232 + #endif
233      integer :: alloc_stat
234      integer :: number_r, number_rho
235  
209
236      status = 0
237      if (EAMList%currentAddition == 0) then
238         call handleError("init_EAM_FF","No members in EAMList")
239         status = -1
240         return
241      end if
242 <
243 <
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
242 >    
243 >    !! Allocate arrays for force calculation
244      
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
245   #ifdef IS_MPI
295    integer :: nAtomsInRow
296    integer :: nAtomsInCol
297 #endif
298    integer :: alloc_stat
299
300
301    status = 0
302 #ifdef IS_MPI
246      nAtomsInRow = getNatomsInRow(plan_atom_row)
247      nAtomsInCol = getNatomsInCol(plan_atom_col)
248   #endif
# Line 310 | Line 253 | contains
253         status = -1
254         return
255      end if
256 +
257      if (allocated(rho)) deallocate(rho)
258      allocate(rho(nlocal),stat=alloc_stat)
259      if (alloc_stat /= 0) then
# Line 324 | Line 268 | contains
268         return
269      end if
270  
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    
271   #ifdef IS_MPI
272  
273      if (allocated(rho_tmp)) deallocate(rho_tmp)
# Line 340 | Line 277 | contains
277         return
278      end if
279  
343
280      if (allocated(frho_row)) deallocate(frho_row)
281      allocate(frho_row(nAtomsInRow),stat=alloc_stat)
282      if (alloc_stat /= 0) then
# Line 359 | Line 295 | contains
295         status = -1
296         return
297      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
298  
299 +    ! Now do column arrays
300  
370 ! Now do column arrays
371
301      if (allocated(frho_col)) deallocate(frho_col)
302      allocate(frho_col(nAtomsInCol),stat=alloc_stat)
303      if (alloc_stat /= 0) then
# Line 387 | Line 316 | contains
316         status = -1
317         return
318      end if
319 <    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 <  
319 >
320   #endif
321  
322 <  end subroutine allocateEAM
322 >  end subroutine init_EAM_FF
323  
324 < !! 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)
324 >  subroutine setCutoffEAM(rcut)
325      real(kind=dp) :: rcut
406    integer :: status
407    status = 0
408
326      EAM_rcut = rcut
410
327    end subroutine setCutoffEAM
328  
413
414
329    subroutine clean_EAM()
330 <  
331 <   ! clean non-IS_MPI first
330 >
331 >    ! clean non-IS_MPI first
332      frho = 0.0_dp
333      rho  = 0.0_dp
334      dfrhodrho = 0.0_dp
335 < ! clean MPI if needed
335 >    ! clean MPI if needed
336   #ifdef IS_MPI
337      frho_row = 0.0_dp
338      frho_col = 0.0_dp
# Line 430 | Line 344 | contains
344   #endif
345    end subroutine clean_EAM
346  
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
347    subroutine deallocate_EAMType(thisEAMType)
348      type (EAMtype), pointer :: thisEAMType
349  
350 <    ! free Arrays in reverse order of allocation...
351 <    deallocate(thisEAMType%eam_phi_r_pp)      
352 <    deallocate(thisEAMType%eam_rho_r_pp)  
353 <    deallocate(thisEAMType%eam_Z_r_pp)  
354 <    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 <  
350 >    call deleteSpline(thisEAMType%F)
351 >    call deleteSpline(thisEAMType%rho)
352 >    call deleteSpline(thisEAMType%phi)
353 >    call deleteSpline(thisEAMType%Z)
354 >
355    end subroutine deallocate_EAMType
356  
357 < !! Calculates rho_r
357 >  !! Calculates rho_r
358    subroutine calc_eam_prepair_rho(atom1,atom2,d,r,rijsq)
359 <    integer :: atom1,atom2
359 >    integer :: atom1, atom2
360      real(kind = dp), dimension(3) :: d
361      real(kind = dp), intent(inout)               :: r
362      real(kind = dp), intent(inout)               :: rijsq
# Line 525 | Line 364 | contains
364      real(kind = dp) :: rho_i_at_j
365      ! value of electron density rho do to atom j at atom i
366      real(kind = dp) :: rho_j_at_i
528
529    ! we don't use the derivatives, dummy variables
530    real( kind = dp) :: drho,d2rho
367      integer :: eam_err
368 <  
369 <    integer :: myid_atom1
370 <    integer :: myid_atom2
368 >    
369 >    integer :: atid1, atid2 ! Global atid    
370 >    integer :: myid_atom1 ! EAM atid
371 >    integer :: myid_atom2
372  
373 < ! check to see if we need to be cleaned at the start of a force loop
537 <      
373 >    ! check to see if we need to be cleaned at the start of a force loop
374  
539
540
375   #ifdef IS_MPI
376 <    myid_atom1 = atid_Row(atom1)
377 <    myid_atom2 = atid_Col(atom2)
376 >    Atid1 = Atid_row(Atom1)
377 >    Atid2 = Atid_col(Atom2)
378   #else
379 <    myid_atom1 = atid(atom1)
380 <    myid_atom2 = atid(atom2)
379 >    Atid1 = Atid(Atom1)
380 >    Atid2 = Atid(Atom2)
381   #endif
382  
383 +    Myid_atom1 = Eamlist%atidtoeamtype(Atid1)
384 +    Myid_atom2 = Eamlist%atidtoeamtype(Atid2)
385 +
386      if (r.lt.EAMList%EAMParams(myid_atom1)%eam_rcut) then
387  
388 +       call lookupUniformSpline(EAMList%EAMParams(myid_atom1)%rho, r, &
389 +            rho_i_at_j)
390  
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      
391   #ifdef  IS_MPI
392         rho_col(atom2) = rho_col(atom2) + rho_i_at_j
393   #else
394         rho(atom2) = rho(atom2) + rho_i_at_j
395   #endif
396 < !       write(*,*) atom1,atom2,r,rho_i_at_j
567 <       endif
396 >    endif
397  
398 <       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)
398 >    if (r.lt.EAMList%EAMParams(myid_atom2)%eam_rcut) then
399  
400 <    
401 <      
402 <      
400 >       call lookupUniformSpline(EAMList%EAMParams(myid_atom2)%rho, r, &
401 >            rho_j_at_i)
402 >
403   #ifdef  IS_MPI
404 <          rho_row(atom1) = rho_row(atom1) + rho_j_at_i
404 >       rho_row(atom1) = rho_row(atom1) + rho_j_at_i
405   #else
406 <          rho(atom1) = rho(atom1) + rho_j_at_i
406 >       rho(atom1) = rho(atom1) + rho_j_at_i
407   #endif
408 <       endif
408 >    endif
409  
586
587
588
589
590
410    end subroutine calc_eam_prepair_rho
411  
412  
594
595
413    !! Calculate the functional F(rho) for all local atoms
414 <  subroutine calc_eam_preforce_Frho(nlocal,pot)
414 >  subroutine calc_eam_preforce_Frho(nlocal, pot)
415      integer :: nlocal
416      real(kind=dp) :: pot
417 <    integer :: i,j
417 >    integer :: i, j
418      integer :: atom
419 <    real(kind=dp) :: U,U1,U2
419 >    real(kind=dp) :: U,U1
420      integer :: atype1
421 <    integer :: me
605 <    integer :: n_rho_points
421 >    integer :: me, atid1
422  
607  
423      cleanme = .true.
424 <    !! Scatter the electron density from  pre-pair calculation back to local atoms
424 >    !! Scatter the electron density from  pre-pair calculation back to
425 >    !! local atoms
426   #ifdef IS_MPI
427      call scatter(rho_row,rho,plan_atom_row,eam_err)
428      if (eam_err /= 0 ) then
429 <      write(errMsg,*) " Error scattering rho_row into rho"
430 <      call handleError(RoutineName,errMesg)
431 <   endif      
429 >       write(errMsg,*) " Error scattering rho_row into rho"
430 >       call handleError(RoutineName,errMesg)
431 >    endif
432      call scatter(rho_col,rho_tmp,plan_atom_col,eam_err)
433      if (eam_err /= 0 ) then
434 <      write(errMsg,*) " Error scattering rho_col into rho"
435 <      call handleError(RoutineName,errMesg)
436 <   endif
434 >       write(errMsg,*) " Error scattering rho_col into rho"
435 >       call handleError(RoutineName,errMesg)
436 >    endif
437  
438 <      rho(1:nlocal) = rho(1:nlocal) + rho_tmp(1:nlocal)
438 >    rho(1:nlocal) = rho(1:nlocal) + rho_tmp(1:nlocal)
439   #endif
440  
441 <
626 <
627 < !! Calculate F(rho) and derivative
441 >    !! Calculate F(rho) and derivative
442      do atom = 1, nlocal
443 <       me = atid(atom)
444 <       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
443 >       atid1 = atid(atom)
444 >       me = eamList%atidToEAMtype(atid1)
445  
446 <
446 >       call lookupUniformSpline1d(EAMList%EAMParams(me)%F, rho(atom), &
447 >            u, u1)
448 >      
449         frho(atom) = u
450         dfrhodrho(atom) = u1
652       d2frhodrhodrho(atom) = u2
451         pot = pot + u
654
452      enddo
453  
657  
658
454   #ifdef IS_MPI
455      !! communicate f(rho) and derivatives back into row and column arrays
456      call gather(frho,frho_row,plan_atom_row, eam_err)
# Line 674 | Line 469 | contains
469      if (eam_err /=  0) then
470         call handleError("cal_eam_forces()","MPI gather dfrhodrho_col failure")
471      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
472   #endif
473  
688  
689  end subroutine calc_eam_preforce_Frho
474  
475 <
476 <
693 <
475 >  end subroutine calc_eam_preforce_Frho
476 >  
477    !! Does EAM pairwise Force calculation.  
478    subroutine do_eam_pair(atom1, atom2, d, rij, r2, sw, vpair, fpair, &
479         pot, f, do_pot)
# Line 703 | Line 486 | contains
486      real( kind = dp ), intent(inout), dimension(3) :: fpair
487  
488      logical, intent(in) :: do_pot
489 <    
490 <    real( kind = dp ) :: drdx,drdy,drdz
491 <    real( kind = dp ) :: d2
492 <    real( kind = dp ) :: phab,pha,dvpdr,d2vpdrdr
493 <    real( kind = dp ) :: rha,drha,d2rha, dpha
711 <    real( kind = dp ) :: rhb,drhb,d2rhb, dphb
489 >
490 >    real( kind = dp ) :: drdx, drdy, drdz
491 >    real( kind = dp ) :: phab, pha, dvpdr
492 >    real( kind = dp ) :: rha, drha, dpha
493 >    real( kind = dp ) :: rhb, drhb, dphb
494      real( kind = dp ) :: dudr
495 <    real( kind = dp ) :: rci,rcj
496 <    real( kind = dp ) :: drhoidr,drhojdr
497 <    real( kind = dp ) :: d2rhoidrdr
498 <    real( kind = dp ) :: d2rhojdrdr
717 <    real( kind = dp ) :: Fx,Fy,Fz
718 <    real( kind = dp ) :: r,d2pha,phb,d2phb
495 >    real( kind = dp ) :: rci, rcj
496 >    real( kind = dp ) :: drhoidr, drhojdr
497 >    real( kind = dp ) :: Fx, Fy, Fz
498 >    real( kind = dp ) :: r, phb
499  
500 <    integer :: id1,id2
500 >    integer :: id1, id2
501      integer  :: mytype_atom1
502      integer  :: mytype_atom2
503 +    integer  :: atid1, atid2
504  
724 !Local Variables
725    
726   ! write(*,*) "Frho: ", Frho(atom1)
727
505      phab = 0.0E0_DP
506      dvpdr = 0.0E0_DP
730    d2vpdrdr = 0.0E0_DP
507  
508      if (rij .lt. EAM_rcut) then
509  
510   #ifdef IS_MPI
511 <       mytype_atom1 = atid_row(atom1)
512 <       mytype_atom2 = atid_col(atom2)
511 >       atid1 = atid_row(atom1)
512 >       atid2 = atid_col(atom2)
513   #else
514 <       mytype_atom1 = atid(atom1)
515 <       mytype_atom2 = atid(atom2)
514 >       atid1 = atid(atom1)
515 >       atid2 = atid(atom2)
516   #endif
517 +
518 +       mytype_atom1 = EAMList%atidToEAMType(atid1)
519 +       mytype_atom2 = EAMList%atidTOEAMType(atid2)
520 +
521 +
522         ! get cutoff for atom 1
523         rci = EAMList%EAMParams(mytype_atom1)%eam_rcut
524         ! get type specific cutoff for atom 2
525         rcj = EAMList%EAMParams(mytype_atom2)%eam_rcut
526 <      
526 >
527         drdx = d(1)/rij
528         drdy = d(2)/rij
529         drdz = d(3)/rij
530 <      
530 >
531         if (rij.lt.rci) then
532 <          call eam_splint(EAMList%EAMParams(mytype_atom1)%eam_nr, &
533 <               EAMList%EAMParams(mytype_atom1)%eam_rvals, &
534 <               EAMList%EAMParams(mytype_atom1)%eam_rho_r, &
535 <               EAMList%EAMParams(mytype_atom1)%eam_rho_r_pp, &
536 <               rij, rha,drha,d2rha)
537 <          !! Calculate Phi(r) for atom1.
538 <          call eam_splint(EAMList%EAMParams(mytype_atom1)%eam_nr, &
539 <               EAMList%EAMParams(mytype_atom1)%eam_rvals, &
540 <               EAMList%EAMParams(mytype_atom1)%eam_phi_r, &
541 <               EAMList%EAMParams(mytype_atom1)%eam_phi_r_pp, &
542 <               rij, pha,dpha,d2pha)
532 >
533 >          ! Calculate rho and drho for atom1
534 >
535 >          call lookupUniformSpline1d(EAMList%EAMParams(mytype_atom1)%rho, &
536 >               rij, rha, drha)
537 >          
538 >          ! Calculate Phi(r) for atom1.
539 >          
540 >          call lookupUniformSpline1d(EAMList%EAMParams(mytype_atom1)%phi, &
541 >               rij, pha, dpha)
542 >
543         endif
544  
545         if (rij.lt.rcj) then      
546 <          ! Calculate rho,drho and d2rho for atom1
547 <          call eam_splint(EAMList%EAMParams(mytype_atom2)%eam_nr, &
548 <               EAMList%EAMParams(mytype_atom2)%eam_rvals, &
549 <               EAMList%EAMParams(mytype_atom2)%eam_rho_r, &
550 <               EAMList%EAMParams(mytype_atom2)%eam_rho_r_pp, &
551 <               rij, rhb,drhb,d2rhb)
552 <          
553 <          !! Calculate Phi(r) for atom2.
554 <          call eam_splint(EAMList%EAMParams(mytype_atom2)%eam_nr, &
555 <               EAMList%EAMParams(mytype_atom2)%eam_rvals, &
556 <               EAMList%EAMParams(mytype_atom2)%eam_phi_r, &
776 <               EAMList%EAMParams(mytype_atom2)%eam_phi_r_pp, &
777 <               rij, phb,dphb,d2phb)
546 >
547 >          ! Calculate rho and drho for atom2
548 >
549 >          call lookupUniformSpline1d(EAMList%EAMParams(mytype_atom2)%rho, &
550 >               rij, rhb, drhb)
551 >
552 >          ! Calculate Phi(r) for atom2.
553 >
554 >          call lookupUniformSpline1d(EAMList%EAMParams(mytype_atom2)%phi, &
555 >               rij, phb, dphb)
556 >
557         endif
558  
559         if (rij.lt.rci) then
560            phab = phab + 0.5E0_DP*(rhb/rha)*pha
561            dvpdr = dvpdr + 0.5E0_DP*((rhb/rha)*dpha + &
562                 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)))
563         endif
564 <      
564 >
565         if (rij.lt.rcj) then
566            phab = phab + 0.5E0_DP*(rha/rhb)*phb
567            dvpdr = dvpdr + 0.5E0_DP*((rha/rhb)*dphb + &
568                 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)))
569         endif
570 <      
570 >
571         drhoidr = drha
572         drhojdr = drhb
573  
803       d2rhoidrdr = d2rha
804       d2rhojdrdr = d2rhb
805
806
574   #ifdef IS_MPI
575         dudr = drhojdr*dfrhodrho_row(atom1)+drhoidr*dfrhodrho_col(atom2) &
576              + dvpdr
# Line 811 | Line 578 | contains
578   #else
579         dudr = drhojdr*dfrhodrho(atom1)+drhoidr*dfrhodrho(atom2) &
580              + dvpdr
814      ! write(*,*) "Atom1,Atom2, dfrhodrho(atom1) dfrhodrho(atom2): ", atom1,atom2,dfrhodrho(atom1),dfrhodrho(atom2)
581   #endif
582  
583         fx = dudr * drdx
# Line 821 | Line 587 | contains
587  
588   #ifdef IS_MPI
589         if (do_pot) then
590 <          pot_Row(atom1) = pot_Row(atom1) + phab*0.5
591 <          pot_Col(atom2) = pot_Col(atom2) + phab*0.5
590 >          pot_Row(METALLIC_POT,atom1) = pot_Row(METALLIC_POT,atom1) + phab*0.5
591 >          pot_Col(METALLIC_POT,atom2) = pot_Col(METALLIC_POT,atom2) + phab*0.5
592         end if
593  
594         f_Row(1,atom1) = f_Row(1,atom1) + fx
595         f_Row(2,atom1) = f_Row(2,atom1) + fy
596         f_Row(3,atom1) = f_Row(3,atom1) + fz
597 <      
597 >
598         f_Col(1,atom2) = f_Col(1,atom2) - fx
599         f_Col(2,atom2) = f_Col(2,atom2) - fy
600         f_Col(3,atom2) = f_Col(3,atom2) - fz
# Line 841 | Line 607 | contains
607         f(1,atom1) = f(1,atom1) + fx
608         f(2,atom1) = f(2,atom1) + fy
609         f(3,atom1) = f(3,atom1) + fz
610 <      
610 >
611         f(1,atom2) = f(1,atom2) - fx
612         f(2,atom2) = f(2,atom2) - fy
613         f(3,atom2) = f(3,atom2) - fz
614   #endif
615 <      
615 >
616         vpair = vpair + phab
617 +
618   #ifdef IS_MPI
619         id1 = AtomRowToGlobal(atom1)
620         id2 = AtomColToGlobal(atom2)
# Line 855 | Line 622 | contains
622         id1 = atom1
623         id2 = atom2
624   #endif
625 <      
625 >
626         if (molMembershipList(id1) .ne. molMembershipList(id2)) then
627 <          
627 >
628            fpair(1) = fpair(1) + fx
629            fpair(2) = fpair(2) + fy
630            fpair(3) = fpair(3) + fz
864          
865       endif
866    
867       if (nmflag) then
631  
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)
632         endif
633      endif
634 +  end subroutine do_eam_pair
635  
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
636   end module eam

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines