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 2204 by gezelter, Fri Apr 15 22:04:00 2005 UTC vs.
Revision 2728 by chrisfen, Fri Apr 21 20:02:19 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 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 117 | Line 101 | module eam
101       integer           :: currentAddition = 0
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 133 | Line 117 | module eam
117    public :: calc_eam_preforce_Frho
118    public :: clean_EAM
119    public :: destroyEAMTypes
120 +  public :: getEAMCut
121 +  public :: lookupEAMSpline
122 +  public :: lookupEAMSpline1d
123  
124   contains
125  
139
126    subroutine newEAMtype(lattice_constant,eam_nrho,eam_drho,eam_nr,&
127 <       eam_dr,rcut,eam_Z_r,eam_rho_r,eam_F_rho,&
142 <       eam_ident,status)
127 >       eam_dr,rcut,eam_Z_r,eam_rho_r,eam_F_rho, c_ident, status)
128      real (kind = dp )                      :: lattice_constant
129      integer                                :: eam_nrho
130      real (kind = dp )                      :: eam_drho
131      integer                                :: eam_nr
132      real (kind = dp )                      :: eam_dr
133      real (kind = dp )                      :: rcut
134 <    real (kind = dp ), dimension(eam_nr)   :: eam_Z_r
135 <    real (kind = dp ), dimension(eam_nr)   :: eam_rho_r
136 <    real (kind = dp ), dimension(eam_nrho) :: eam_F_rho
137 <    integer                                :: eam_ident
134 >    real (kind = dp ), dimension(eam_nr)   :: eam_Z_r, rvals
135 >    real (kind = dp ), dimension(eam_nr)   :: eam_rho_r, eam_phi_r
136 >    real (kind = dp ), dimension(eam_nrho) :: eam_F_rho, rhovals
137 >    integer                                :: c_ident
138      integer                                :: status
139  
140 <    integer                                :: nAtypes
140 >    integer                                :: nAtypes,nEAMTypes,myATID
141      integer                                :: maxVals
142      integer                                :: alloc_stat
143 <    integer                                :: current
143 >    integer                                :: current, j
144      integer,pointer                        :: Matchlist(:) => null()
145  
146      status = 0
147  
163
148      !! Assume that atypes has already been set and get the total number of types in atypes
149      !! Also assume that every member of atypes is a EAM model.
150  
167
151      ! check to see if this is the first time into
152      if (.not.associated(EAMList%EAMParams)) then
153 <       call getMatchingElementList(atypes, "is_EAM", .true., nAtypes, MatchList)
154 <       EAMList%n_eam_types = nAtypes
155 <       allocate(EAMList%EAMParams(nAtypes))
153 >       call getMatchingElementList(atypes, "is_EAM", .true., nEAMtypes, MatchList)
154 >       EAMList%n_eam_types = nEAMtypes
155 >       allocate(EAMList%EAMParams(nEAMTypes))
156 >       nAtypes = getSize(atypes)
157 >       allocate(EAMList%atidToEAMType(nAtypes))
158      end if
159  
160      EAMList%currentAddition = EAMList%currentAddition + 1
161      current = EAMList%currentAddition
162  
163 +    myATID =  getFirstMatchingElement(atypes, "c_ident", c_ident)
164 +    EAMList%atidToEAMType(myATID) = current
165  
166 <    call allocate_EAMType(eam_nrho,eam_nr,EAMList%EAMParams(current),stat=alloc_stat)
180 <    if (alloc_stat /= 0) then
181 <       status = -1
182 <       return
183 <    end if
184 <
185 <    ! this is a possible bug, we assume a correspondence between the vector atypes and
186 <    ! EAMAtypes
187 <
188 <    EAMList%EAMParams(current)%eam_atype    = eam_ident
166 >    EAMList%EAMParams(current)%eam_atype    = c_ident
167      EAMList%EAMParams(current)%eam_lattice  = lattice_constant
190    EAMList%EAMParams(current)%eam_nrho     = eam_nrho
191    EAMList%EAMParams(current)%eam_drho     = eam_drho
192    EAMList%EAMParams(current)%eam_nr       = eam_nr
193    EAMList%EAMParams(current)%eam_dr       = eam_dr
168      EAMList%EAMParams(current)%eam_rcut     = rcut
169 <    EAMList%EAMParams(current)%eam_Z_r      = eam_Z_r
170 <    EAMList%EAMParams(current)%eam_rho_r    = eam_rho_r
171 <    EAMList%EAMParams(current)%eam_F_rho    = eam_F_rho
169 >
170 >    ! Build array of r values
171 >    do j = 1, eam_nr
172 >       rvals(j) = real(j-1,kind=dp) * eam_dr
173 >    end do
174 >    
175 >    ! Build array of rho values
176 >    do j = 1, eam_nrho
177 >       rhovals(j) = real(j-1,kind=dp) * eam_drho
178 >    end do
179 >
180 >    ! convert from eV to kcal / mol:
181 >    do j = 1, eam_nrho
182 >       eam_F_rho(j) = eam_F_rho(j) * 23.06054E0_DP
183 >    end do
184 >    
185 >    ! precompute the pair potential and get it into kcal / mol:
186 >    eam_phi_r(1) = 0.0E0_DP
187 >    do j = 2, eam_nr
188 >       eam_phi_r(j) = 331.999296E0_DP * (eam_Z_r(j)**2) / rvals(j)
189 >    enddo
190  
191 +    call newSpline(EAMList%EAMParams(current)%rho, rvals, eam_rho_r, .true.)
192 +    call newSpline(EAMList%EAMParams(current)%Z,   rvals, eam_Z_r, .true.)
193 +    call newSpline(EAMList%EAMParams(current)%F, rhovals, eam_F_rho, .true.)
194 +    call newSpline(EAMList%EAMParams(current)%phi, rvals, eam_phi_r, .true.)
195    end subroutine newEAMtype
196  
197  
# Line 213 | Line 209 | contains
209  
210      eamList%n_eam_types = 0
211      eamList%currentAddition = 0
216
212    end subroutine destroyEAMtypes
213  
214 +  function getEAMCut(atomID) result(cutValue)
215 +    integer, intent(in) :: atomID
216 +    integer :: eamID
217 +    real(kind=dp) :: cutValue
218 +    
219 +    eamID = EAMList%atidToEAMType(atomID)
220 +    cutValue = EAMList%EAMParams(eamID)%eam_rcut
221 +  end function getEAMCut
222 +
223    subroutine init_EAM_FF(status)
224      integer :: status
225      integer :: i,j
226      real(kind=dp) :: current_rcut_max
227 + #ifdef IS_MPI
228 +    integer :: nAtomsInRow
229 +    integer :: nAtomsInCol
230 + #endif
231      integer :: alloc_stat
232      integer :: number_r, number_rho
233  
226
234      status = 0
235      if (EAMList%currentAddition == 0) then
236         call handleError("init_EAM_FF","No members in EAMList")
237         status = -1
238         return
239      end if
240 <
234 <
235 <    do i = 1, EAMList%currentAddition
236 <
237 <       ! Build array of r values
238 <
239 <       do j = 1,EAMList%EAMParams(i)%eam_nr
240 <          EAMList%EAMParams(i)%eam_rvals(j) = &
241 <               real(j-1,kind=dp)* &
242 <               EAMList%EAMParams(i)%eam_dr
243 <       end do
244 <       ! Build array of rho values
245 <       do j = 1,EAMList%EAMParams(i)%eam_nrho
246 <          EAMList%EAMParams(i)%eam_rhovals(j) = &
247 <               real(j-1,kind=dp)* &
248 <               EAMList%EAMParams(i)%eam_drho
249 <       end do
250 <       ! convert from eV to kcal / mol:
251 <       EAMList%EAMParams(i)%eam_F_rho = EAMList%EAMParams(i)%eam_F_rho * 23.06054E0_DP
252 <
253 <       ! precompute the pair potential and get it into kcal / mol:
254 <       EAMList%EAMParams(i)%eam_phi_r(1) = 0.0E0_DP
255 <       do j = 2, EAMList%EAMParams(i)%eam_nr
256 <          EAMList%EAMParams(i)%eam_phi_r(j) = (EAMList%EAMParams(i)%eam_Z_r(j)**2)/EAMList%EAMParams(i)%eam_rvals(j)
257 <          EAMList%EAMParams(i)%eam_phi_r(j) =  EAMList%EAMParams(i)%eam_phi_r(j)*331.999296E0_DP
258 <       enddo
259 <    end do
260 <
261 <
262 <    do i = 1,  EAMList%currentAddition
263 <       number_r   = EAMList%EAMParams(i)%eam_nr
264 <       number_rho = EAMList%EAMParams(i)%eam_nrho
265 <
266 <       call eam_spline(number_r, EAMList%EAMParams(i)%eam_rvals, &
267 <            EAMList%EAMParams(i)%eam_rho_r, &
268 <            EAMList%EAMParams(i)%eam_rho_r_pp, &
269 <            0.0E0_DP, 0.0E0_DP, 'N')
270 <       call eam_spline(number_r, EAMList%EAMParams(i)%eam_rvals, &
271 <            EAMList%EAMParams(i)%eam_Z_r, &
272 <            EAMList%EAMParams(i)%eam_Z_r_pp, &
273 <            0.0E0_DP, 0.0E0_DP, 'N')
274 <       call eam_spline(number_rho, EAMList%EAMParams(i)%eam_rhovals, &
275 <            EAMList%EAMParams(i)%eam_F_rho, &
276 <            EAMList%EAMParams(i)%eam_F_rho_pp, &
277 <            0.0E0_DP, 0.0E0_DP, 'N')
278 <       call eam_spline(number_r, EAMList%EAMParams(i)%eam_rvals, &
279 <            EAMList%EAMParams(i)%eam_phi_r, &
280 <            EAMList%EAMParams(i)%eam_phi_r_pp, &
281 <            0.0E0_DP, 0.0E0_DP, 'N')
282 <    enddo
283 <
284 <    !       current_rcut_max = EAMList%EAMParams(1)%eam_rcut
285 <    !! find the smallest rcut for any eam atype
286 <    !       do i = 2, EAMList%currentAddition
287 <    !          current_rcut_max =max(current_rcut_max,EAMList%EAMParams(i)%eam_rcut)
288 <    !       end do
289 <
290 <    !       EAM_rcut = current_rcut_max
291 <    !       EAM_rcut_orig = current_rcut_max
292 <    !       do i = 1, EAMList%currentAddition
293 <    !          EAMList%EAMParam(i)s%eam_atype_map(eam_atype(i)) = i
294 <    !       end do
240 >    
241      !! Allocate arrays for force calculation
242 <
297 <    call allocateEAM(alloc_stat)
298 <    if (alloc_stat /= 0 ) then
299 <       write(*,*) "allocateEAM failed"
300 <       status = -1
301 <       return
302 <    endif
303 <
304 <  end subroutine init_EAM_FF
305 <
306 <  !! routine checks to see if array is allocated, deallocates array if allocated
307 <  !! and then creates the array to the required size
308 <  subroutine allocateEAM(status)
309 <    integer, intent(out) :: status
310 <
242 >    
243   #ifdef IS_MPI
312    integer :: nAtomsInRow
313    integer :: nAtomsInCol
314 #endif
315    integer :: alloc_stat
316
317
318    status = 0
319 #ifdef IS_MPI
244      nAtomsInRow = getNatomsInRow(plan_atom_row)
245      nAtomsInCol = getNatomsInCol(plan_atom_col)
246   #endif
# Line 327 | Line 251 | contains
251         status = -1
252         return
253      end if
254 +
255      if (allocated(rho)) deallocate(rho)
256      allocate(rho(nlocal),stat=alloc_stat)
257      if (alloc_stat /= 0) then
# Line 341 | Line 266 | contains
266         return
267      end if
268  
344    if (allocated(d2frhodrhodrho)) deallocate(d2frhodrhodrho)
345    allocate(d2frhodrhodrho(nlocal),stat=alloc_stat)
346    if (alloc_stat /= 0) then
347       status = -1
348       return
349    end if
350
269   #ifdef IS_MPI
270  
271      if (allocated(rho_tmp)) deallocate(rho_tmp)
# Line 357 | Line 275 | contains
275         return
276      end if
277  
360
278      if (allocated(frho_row)) deallocate(frho_row)
279      allocate(frho_row(nAtomsInRow),stat=alloc_stat)
280      if (alloc_stat /= 0) then
# Line 376 | Line 293 | contains
293         status = -1
294         return
295      end if
379    if (allocated(d2frhodrhodrho_row)) deallocate(d2frhodrhodrho_row)
380    allocate(d2frhodrhodrho_row(nAtomsInRow),stat=alloc_stat)
381    if (alloc_stat /= 0) then
382       status = -1
383       return
384    end if
296  
386
297      ! Now do column arrays
298  
299      if (allocated(frho_col)) deallocate(frho_col)
# Line 404 | Line 314 | contains
314         status = -1
315         return
316      end if
407    if (allocated(d2frhodrhodrho_col)) deallocate(d2frhodrhodrho_col)
408    allocate(d2frhodrhodrho_col(nAtomsInCol),stat=alloc_stat)
409    if (alloc_stat /= 0) then
410       status = -1
411       return
412    end if
317  
318   #endif
319  
320 <  end subroutine allocateEAM
320 >  end subroutine init_EAM_FF
321  
322 <  !! C sets rcut to be the largest cutoff of any atype
419 <  !! present in this simulation. Doesn't include all atypes
420 <  !! sim knows about, just those in the simulation.
421 <  subroutine setCutoffEAM(rcut, status)
322 >  subroutine setCutoffEAM(rcut)
323      real(kind=dp) :: rcut
423    integer :: status
424    status = 0
425
324      EAM_rcut = rcut
427
325    end subroutine setCutoffEAM
326  
430
431
327    subroutine clean_EAM()
328  
329      ! clean non-IS_MPI first
# Line 447 | Line 342 | contains
342   #endif
343    end subroutine clean_EAM
344  
450
451
452  subroutine allocate_EAMType(eam_n_rho,eam_n_r,thisEAMType,stat)
453    integer, intent(in)          :: eam_n_rho
454    integer, intent(in)          :: eam_n_r
455    type (EAMType)               :: thisEAMType
456    integer, optional   :: stat
457    integer             :: alloc_stat
458
459
460
461    if (present(stat)) stat = 0
462
463    allocate(thisEAMType%eam_rvals(eam_n_r),stat=alloc_stat)  
464    if (alloc_stat /= 0 ) then
465       if (present(stat)) stat = -1
466       return
467    end if
468    allocate(thisEAMType%eam_rhovals(eam_n_rho),stat=alloc_stat)  
469    if (alloc_stat /= 0 ) then
470       if (present(stat)) stat = -1
471       return
472    end if
473    allocate(thisEAMType%eam_F_rho(eam_n_rho),stat=alloc_stat)  
474    if (alloc_stat /= 0 ) then
475       if (present(stat)) stat = -1
476       return
477    end if
478    allocate(thisEAMType%eam_Z_r(eam_n_r),stat=alloc_stat)        
479    if (alloc_stat /= 0 ) then
480       if (present(stat)) stat = -1
481       return
482    end if
483    allocate(thisEAMType%eam_rho_r(eam_n_r),stat=alloc_stat)      
484    if (alloc_stat /= 0 ) then
485       if (present(stat)) stat = -1
486       return
487    end if
488    allocate(thisEAMType%eam_phi_r(eam_n_r),stat=alloc_stat)      
489    if (alloc_stat /= 0 ) then
490       if (present(stat)) stat = -1
491       return
492    end if
493    allocate(thisEAMType%eam_F_rho_pp(eam_n_rho),stat=alloc_stat)  
494    if (alloc_stat /= 0 ) then
495       if (present(stat)) stat = -1
496       return
497    end if
498    allocate(thisEAMType%eam_Z_r_pp(eam_n_r),stat=alloc_stat)  
499    if (alloc_stat /= 0 ) then
500       if (present(stat)) stat = -1
501       return
502    end if
503    allocate(thisEAMType%eam_rho_r_pp(eam_n_r),stat=alloc_stat)  
504    if (alloc_stat /= 0 ) then
505       if (present(stat)) stat = -1
506       return
507    end if
508    allocate(thisEAMType%eam_phi_r_pp(eam_n_r),stat=alloc_stat)
509    if (alloc_stat /= 0 ) then
510       if (present(stat)) stat = -1
511       return
512    end if
513
514
515  end subroutine allocate_EAMType
516
517
345    subroutine deallocate_EAMType(thisEAMType)
346      type (EAMtype), pointer :: thisEAMType
347  
348 <    ! free Arrays in reverse order of allocation...
349 <    if(associated(thisEAMType%eam_phi_r_pp)) deallocate(thisEAMType%eam_phi_r_pp)      
350 <    if(associated(thisEAMType%eam_rho_r_pp)) deallocate(thisEAMType%eam_rho_r_pp)  
351 <    if(associated(thisEAMType%eam_Z_r_pp)) deallocate(thisEAMType%eam_Z_r_pp)  
525 <    if(associated(thisEAMType%eam_F_rho_pp)) deallocate(thisEAMType%eam_F_rho_pp)  
526 <    if(associated(thisEAMType%eam_phi_r)) deallocate(thisEAMType%eam_phi_r)      
527 <    if(associated(thisEAMType%eam_rho_r)) deallocate(thisEAMType%eam_rho_r)      
528 <    if(associated(thisEAMType%eam_Z_r)) deallocate(thisEAMType%eam_Z_r)  
529 <    if(associated(thisEAMType%eam_F_rho)) deallocate(thisEAMType%eam_F_rho)
530 <    if(associated(thisEAMType%eam_rhovals)) deallocate(thisEAMType%eam_rhovals)
531 <    if(associated(thisEAMType%eam_rvals)) deallocate(thisEAMType%eam_rvals)
348 >    call deleteSpline(thisEAMType%F)
349 >    call deleteSpline(thisEAMType%rho)
350 >    call deleteSpline(thisEAMType%phi)
351 >    call deleteSpline(thisEAMType%Z)
352  
353    end subroutine deallocate_EAMType
354  
355    !! Calculates rho_r
356    subroutine calc_eam_prepair_rho(atom1,atom2,d,r,rijsq)
357 <    integer :: atom1,atom2
357 >    integer :: atom1, atom2
358      real(kind = dp), dimension(3) :: d
359      real(kind = dp), intent(inout)               :: r
360      real(kind = dp), intent(inout)               :: rijsq
# Line 542 | Line 362 | contains
362      real(kind = dp) :: rho_i_at_j
363      ! value of electron density rho do to atom j at atom i
364      real(kind = dp) :: rho_j_at_i
545
546    ! we don't use the derivatives, dummy variables
547    real( kind = dp) :: drho,d2rho
365      integer :: eam_err
366 +    
367 +    integer :: atid1, atid2 ! Global atid    
368 +    integer :: myid_atom1 ! EAM atid
369 +    integer :: myid_atom2
370  
550    integer :: myid_atom1
551    integer :: myid_atom2
552
371      ! check to see if we need to be cleaned at the start of a force loop
372  
555
556
557
373   #ifdef IS_MPI
374 <    myid_atom1 = atid_Row(atom1)
375 <    myid_atom2 = atid_Col(atom2)
374 >    Atid1 = Atid_row(Atom1)
375 >    Atid2 = Atid_col(Atom2)
376   #else
377 <    myid_atom1 = atid(atom1)
378 <    myid_atom2 = atid(atom2)
377 >    Atid1 = Atid(Atom1)
378 >    Atid2 = Atid(Atom2)
379   #endif
380  
381 +    Myid_atom1 = Eamlist%atidtoeamtype(Atid1)
382 +    Myid_atom2 = Eamlist%atidtoeamtype(Atid2)
383 +
384      if (r.lt.EAMList%EAMParams(myid_atom1)%eam_rcut) then
385  
386 +       call lookupEAMSpline(EAMList%EAMParams(myid_atom1)%rho, r, &
387 +            rho_i_at_j)
388  
569
570       call eam_splint(EAMList%EAMParams(myid_atom1)%eam_nr, &
571            EAMList%EAMParams(myid_atom1)%eam_rvals, &
572            EAMList%EAMParams(myid_atom1)%eam_rho_r, &
573            EAMList%EAMParams(myid_atom1)%eam_rho_r_pp, &
574            r, rho_i_at_j,drho,d2rho)
575
576
577
389   #ifdef  IS_MPI
390         rho_col(atom2) = rho_col(atom2) + rho_i_at_j
391   #else
392         rho(atom2) = rho(atom2) + rho_i_at_j
393   #endif
583       !       write(*,*) atom1,atom2,r,rho_i_at_j
394      endif
395  
396      if (r.lt.EAMList%EAMParams(myid_atom2)%eam_rcut) then
397 <       call eam_splint(EAMList%EAMParams(myid_atom2)%eam_nr, &
398 <            EAMList%EAMParams(myid_atom2)%eam_rvals, &
399 <            EAMList%EAMParams(myid_atom2)%eam_rho_r, &
590 <            EAMList%EAMParams(myid_atom2)%eam_rho_r_pp, &
591 <            r, rho_j_at_i,drho,d2rho)
397 >
398 >       call lookupEAMSpline(EAMList%EAMParams(myid_atom2)%rho, r, &
399 >            rho_j_at_i)
400  
593
594
595
401   #ifdef  IS_MPI
402         rho_row(atom1) = rho_row(atom1) + rho_j_at_i
403   #else
404         rho(atom1) = rho(atom1) + rho_j_at_i
405   #endif
406      endif
602
603
604
605
606
607
407    end subroutine calc_eam_prepair_rho
408  
409  
611
612
410    !! Calculate the functional F(rho) for all local atoms
411 <  subroutine calc_eam_preforce_Frho(nlocal,pot)
411 >  subroutine calc_eam_preforce_Frho(nlocal, pot)
412      integer :: nlocal
413      real(kind=dp) :: pot
414 <    integer :: i,j
414 >    integer :: i, j
415      integer :: atom
416 <    real(kind=dp) :: U,U1,U2
416 >    real(kind=dp) :: U,U1
417      integer :: atype1
418 <    integer :: me
622 <    integer :: n_rho_points
418 >    integer :: me, atid1
419  
624
420      cleanme = .true.
421 <    !! Scatter the electron density from  pre-pair calculation back to local atoms
421 >    !! Scatter the electron density from  pre-pair calculation back to
422 >    !! local atoms
423   #ifdef IS_MPI
424      call scatter(rho_row,rho,plan_atom_row,eam_err)
425      if (eam_err /= 0 ) then
# Line 639 | Line 435 | contains
435      rho(1:nlocal) = rho(1:nlocal) + rho_tmp(1:nlocal)
436   #endif
437  
642
643
438      !! Calculate F(rho) and derivative
439      do atom = 1, nlocal
440 <       me = atid(atom)
441 <       n_rho_points = EAMList%EAMParams(me)%eam_nrho
648 <       !  Check to see that the density is not greater than the larges rho we have calculated
649 <       if (rho(atom) < EAMList%EAMParams(me)%eam_rhovals(n_rho_points)) then
650 <          call eam_splint(n_rho_points, &
651 <               EAMList%EAMParams(me)%eam_rhovals, &
652 <               EAMList%EAMParams(me)%eam_f_rho, &
653 <               EAMList%EAMParams(me)%eam_f_rho_pp, &
654 <               rho(atom), & ! Actual Rho
655 <               u, u1, u2)
656 <       else
657 <          ! Calculate F(rho with the largest available rho value
658 <          call eam_splint(n_rho_points, &
659 <               EAMList%EAMParams(me)%eam_rhovals, &
660 <               EAMList%EAMParams(me)%eam_f_rho, &
661 <               EAMList%EAMParams(me)%eam_f_rho_pp, &
662 <               EAMList%EAMParams(me)%eam_rhovals(n_rho_points), & ! Largest rho
663 <               u,u1,u2)
664 <       end if
440 >       atid1 = atid(atom)
441 >       me = eamList%atidToEAMtype(atid1)
442  
443 <
443 >       call lookupEAMSpline1d(EAMList%EAMParams(me)%F, rho(atom), &
444 >            u, u1)
445 >      
446         frho(atom) = u
447         dfrhodrho(atom) = u1
669       d2frhodrhodrho(atom) = u2
448         pot = pot + u
449  
450      enddo
451  
674
675
452   #ifdef IS_MPI
453      !! communicate f(rho) and derivatives back into row and column arrays
454      call gather(frho,frho_row,plan_atom_row, eam_err)
# Line 691 | Line 467 | contains
467      if (eam_err /=  0) then
468         call handleError("cal_eam_forces()","MPI gather dfrhodrho_col failure")
469      endif
694
695
696
697
698
699    if (nmflag) then
700       call gather(d2frhodrhodrho,d2frhodrhodrho_row,plan_atom_row)
701       call gather(d2frhodrhodrho,d2frhodrhodrho_col,plan_atom_col)
702    endif
470   #endif
471  
472  
473    end subroutine calc_eam_preforce_Frho
474 <
708 <
709 <
710 <
474 >  
475    !! Does EAM pairwise Force calculation.  
476    subroutine do_eam_pair(atom1, atom2, d, rij, r2, sw, vpair, fpair, &
477         pot, f, do_pot)
# Line 721 | Line 485 | contains
485  
486      logical, intent(in) :: do_pot
487  
488 <    real( kind = dp ) :: drdx,drdy,drdz
489 <    real( kind = dp ) :: d2
490 <    real( kind = dp ) :: phab,pha,dvpdr,d2vpdrdr
491 <    real( kind = dp ) :: rha,drha,d2rha, dpha
728 <    real( kind = dp ) :: rhb,drhb,d2rhb, dphb
488 >    real( kind = dp ) :: drdx, drdy, drdz
489 >    real( kind = dp ) :: phab, pha, dvpdr
490 >    real( kind = dp ) :: rha, drha, dpha
491 >    real( kind = dp ) :: rhb, drhb, dphb
492      real( kind = dp ) :: dudr
493 <    real( kind = dp ) :: rci,rcj
494 <    real( kind = dp ) :: drhoidr,drhojdr
495 <    real( kind = dp ) :: d2rhoidrdr
496 <    real( kind = dp ) :: d2rhojdrdr
734 <    real( kind = dp ) :: Fx,Fy,Fz
735 <    real( kind = dp ) :: r,d2pha,phb,d2phb
493 >    real( kind = dp ) :: rci, rcj
494 >    real( kind = dp ) :: drhoidr, drhojdr
495 >    real( kind = dp ) :: Fx, Fy, Fz
496 >    real( kind = dp ) :: r, phb
497  
498 <    integer :: id1,id2
498 >    integer :: id1, id2
499      integer  :: mytype_atom1
500      integer  :: mytype_atom2
501 +    integer  :: atid1, atid2
502  
741    !Local Variables
742
743    ! write(*,*) "Frho: ", Frho(atom1)
744
503      phab = 0.0E0_DP
504      dvpdr = 0.0E0_DP
747    d2vpdrdr = 0.0E0_DP
505  
506      if (rij .lt. EAM_rcut) then
507  
508   #ifdef IS_MPI
509 <       mytype_atom1 = atid_row(atom1)
510 <       mytype_atom2 = atid_col(atom2)
509 >       atid1 = atid_row(atom1)
510 >       atid2 = atid_col(atom2)
511   #else
512 <       mytype_atom1 = atid(atom1)
513 <       mytype_atom2 = atid(atom2)
512 >       atid1 = atid(atom1)
513 >       atid2 = atid(atom2)
514   #endif
515 +
516 +       mytype_atom1 = EAMList%atidToEAMType(atid1)
517 +       mytype_atom2 = EAMList%atidTOEAMType(atid2)
518 +
519 +
520         ! get cutoff for atom 1
521         rci = EAMList%EAMParams(mytype_atom1)%eam_rcut
522         ! get type specific cutoff for atom 2
# Line 765 | Line 527 | contains
527         drdz = d(3)/rij
528  
529         if (rij.lt.rci) then
530 <          call eam_splint(EAMList%EAMParams(mytype_atom1)%eam_nr, &
531 <               EAMList%EAMParams(mytype_atom1)%eam_rvals, &
532 <               EAMList%EAMParams(mytype_atom1)%eam_rho_r, &
533 <               EAMList%EAMParams(mytype_atom1)%eam_rho_r_pp, &
534 <               rij, rha,drha,d2rha)
535 <          !! Calculate Phi(r) for atom1.
536 <          call eam_splint(EAMList%EAMParams(mytype_atom1)%eam_nr, &
537 <               EAMList%EAMParams(mytype_atom1)%eam_rvals, &
538 <               EAMList%EAMParams(mytype_atom1)%eam_phi_r, &
539 <               EAMList%EAMParams(mytype_atom1)%eam_phi_r_pp, &
540 <               rij, pha,dpha,d2pha)
530 >
531 >          ! Calculate rho and drho for atom1
532 >
533 >          call lookupEAMSpline1d(EAMList%EAMParams(mytype_atom1)%rho, &
534 >               rij, rha, drha)
535 >          
536 >          ! Calculate Phi(r) for atom1.
537 >          
538 >          call lookupEAMSpline1d(EAMList%EAMParams(mytype_atom1)%phi, &
539 >               rij, pha, dpha)
540 >
541         endif
542  
543         if (rij.lt.rcj) then      
782          ! Calculate rho,drho and d2rho for atom1
783          call eam_splint(EAMList%EAMParams(mytype_atom2)%eam_nr, &
784               EAMList%EAMParams(mytype_atom2)%eam_rvals, &
785               EAMList%EAMParams(mytype_atom2)%eam_rho_r, &
786               EAMList%EAMParams(mytype_atom2)%eam_rho_r_pp, &
787               rij, rhb,drhb,d2rhb)
544  
545 <          !! Calculate Phi(r) for atom2.
546 <          call eam_splint(EAMList%EAMParams(mytype_atom2)%eam_nr, &
547 <               EAMList%EAMParams(mytype_atom2)%eam_rvals, &
548 <               EAMList%EAMParams(mytype_atom2)%eam_phi_r, &
549 <               EAMList%EAMParams(mytype_atom2)%eam_phi_r_pp, &
550 <               rij, phb,dphb,d2phb)
545 >          ! Calculate rho and drho for atom2
546 >
547 >          call lookupEAMSpline1d(EAMList%EAMParams(mytype_atom2)%rho, &
548 >               rij, rhb, drhb)
549 >
550 >          ! Calculate Phi(r) for atom2.
551 >
552 >          call lookupEAMSpline1d(EAMList%EAMParams(mytype_atom2)%phi, &
553 >               rij, phb, dphb)
554 >
555         endif
556  
557         if (rij.lt.rci) then
558            phab = phab + 0.5E0_DP*(rhb/rha)*pha
559            dvpdr = dvpdr + 0.5E0_DP*((rhb/rha)*dpha + &
560                 pha*((drhb/rha) - (rhb*drha/rha/rha)))
801          d2vpdrdr = d2vpdrdr + 0.5E0_DP*((rhb/rha)*d2pha + &
802               2.0E0_DP*dpha*((drhb/rha) - (rhb*drha/rha/rha)) + &
803               pha*((d2rhb/rha) - 2.0E0_DP*(drhb*drha/rha/rha) + &
804               (2.0E0_DP*rhb*drha*drha/rha/rha/rha) - (rhb*d2rha/rha/rha)))
561         endif
562  
563         if (rij.lt.rcj) then
564            phab = phab + 0.5E0_DP*(rha/rhb)*phb
565            dvpdr = dvpdr + 0.5E0_DP*((rha/rhb)*dphb + &
566                 phb*((drha/rhb) - (rha*drhb/rhb/rhb)))
811          d2vpdrdr = d2vpdrdr + 0.5E0_DP*((rha/rhb)*d2phb + &
812               2.0E0_DP*dphb*((drha/rhb) - (rha*drhb/rhb/rhb)) + &
813               phb*((d2rha/rhb) - 2.0E0_DP*(drha*drhb/rhb/rhb) + &
814               (2.0E0_DP*rha*drhb*drhb/rhb/rhb/rhb) - (rha*d2rhb/rhb/rhb)))
567         endif
568  
569         drhoidr = drha
570         drhojdr = drhb
571  
820       d2rhoidrdr = d2rha
821       d2rhojdrdr = d2rhb
822
823
572   #ifdef IS_MPI
573         dudr = drhojdr*dfrhodrho_row(atom1)+drhoidr*dfrhodrho_col(atom2) &
574              + dvpdr
# Line 828 | Line 576 | contains
576   #else
577         dudr = drhojdr*dfrhodrho(atom1)+drhoidr*dfrhodrho(atom2) &
578              + dvpdr
831       ! write(*,*) "Atom1,Atom2, dfrhodrho(atom1) dfrhodrho(atom2): ", atom1,atom2,dfrhodrho(atom1),dfrhodrho(atom2)
579   #endif
580  
581         fx = dudr * drdx
# Line 838 | Line 585 | contains
585  
586   #ifdef IS_MPI
587         if (do_pot) then
588 <          pot_Row(atom1) = pot_Row(atom1) + phab*0.5
589 <          pot_Col(atom2) = pot_Col(atom2) + phab*0.5
588 >          pot_Row(METALLIC_POT,atom1) = pot_Row(METALLIC_POT,atom1) + phab*0.5
589 >          pot_Col(METALLIC_POT,atom2) = pot_Col(METALLIC_POT,atom2) + phab*0.5
590         end if
591  
592         f_Row(1,atom1) = f_Row(1,atom1) + fx
# Line 865 | Line 612 | contains
612   #endif
613  
614         vpair = vpair + phab
615 +
616   #ifdef IS_MPI
617         id1 = AtomRowToGlobal(atom1)
618         id2 = AtomColToGlobal(atom2)
# Line 880 | Line 628 | contains
628            fpair(3) = fpair(3) + fz
629  
630         endif
883
884       if (nmflag) then
885
886          drhoidr = drha
887          drhojdr = drhb
888          d2rhoidrdr = d2rha
889          d2rhojdrdr = d2rhb
890
891 #ifdef IS_MPI
892          d2 = d2vpdrdr + &
893               d2rhoidrdr*dfrhodrho_col(atom2) + &
894               d2rhojdrdr*dfrhodrho_row(atom1) + &
895               drhoidr*drhoidr*d2frhodrhodrho_col(atom2) + &
896               drhojdr*drhojdr*d2frhodrhodrho_row(atom1)
897
898 #else
899
900          d2 = d2vpdrdr + &
901               d2rhoidrdr*dfrhodrho(atom2) + &
902               d2rhojdrdr*dfrhodrho(atom1) + &
903               drhoidr*drhoidr*d2frhodrhodrho(atom2) + &
904               drhojdr*drhojdr*d2frhodrhodrho(atom1)
905 #endif
906       end if
907
631      endif
632    end subroutine do_eam_pair
633  
634 +  subroutine lookupEAMSpline(cs, xval, yval)
635 +    
636 +    implicit none
637  
638 <  subroutine eam_splint(nx, xa, ya, yppa, x, y, dy, d2y)
638 >    type (cubicSpline), intent(in) :: cs
639 >    real( kind = DP ), intent(in)  :: xval
640 >    real( kind = DP ), intent(out) :: yval
641 >    real( kind = DP ) ::  dx
642 >    integer :: i, j
643 >    !
644 >    !  Find the interval J = [ cs%x(J), cs%x(J+1) ] that contains
645 >    !  or is nearest to xval.
646 >    
647 >    j = MAX(1, MIN(cs%n-1, idint((xval-cs%x(1)) * cs%dx_i) + 1))
648 >    
649 >    dx = xval - cs%x(j)
650 >    yval = cs%y(j) + dx*(cs%b(j) + dx*(cs%c(j) + dx*cs%d(j)))
651 >    
652 >    return
653 >  end subroutine lookupEAMSpline
654  
655 <    integer :: atype, nx, j
656 <    real( kind = DP ), dimension(:) :: xa
657 <    real( kind = DP ), dimension(:) :: ya
917 <    real( kind = DP ), dimension(:) :: yppa
918 <    real( kind = DP ) :: x, y
919 <    real( kind = DP ) :: dy, d2y
920 <    real( kind = DP ) :: del, h, a, b, c, d
921 <    integer :: pp_arraySize
655 >  subroutine lookupEAMSpline1d(cs, xval, yval, dydx)
656 >    
657 >    implicit none
658  
659 +    type (cubicSpline), intent(in) :: cs
660 +    real( kind = DP ), intent(in)  :: xval
661 +    real( kind = DP ), intent(out) :: yval, dydx
662 +    real( kind = DP ) :: dx
663 +    integer :: i, j
664 +    
665 +    !  Find the interval J = [ cs%x(J), cs%x(J+1) ] that contains
666 +    !  or is nearest to xval.
667  
924    ! this spline code assumes that the x points are equally spaced
925    ! do not attempt to use this code if they are not.
668  
669 +    j = MAX(1, MIN(cs%n-1, idint((xval-cs%x(1)) * cs%dx_i) + 1))
670 +    
671 +    dx = xval - cs%x(j)
672 +    yval = cs%y(j) + dx*(cs%b(j) + dx*(cs%c(j) + dx*cs%d(j)))
673  
674 <    ! find the closest point with a value below our own:
675 <    j = FLOOR(real((nx-1),kind=dp) * (x - xa(1)) / (xa(nx) - xa(1))) + 1
674 >    dydx = cs%b(j) + dx*(2.0d0 * cs%c(j) + 3.0d0 * dx * cs%d(j))
675 >      
676 >    return
677 >  end subroutine lookupEAMSpline1d
678  
931    ! check to make sure we're inside the spline range:
932    if ((j.gt.nx).or.(j.lt.1)) then
933       write(errMSG,*) "EAM_splint: x is outside bounds of spline: ",x,j
934       call handleError(routineName,errMSG)
935    endif
936    ! check to make sure we haven't screwed up the calculation of j:
937    if ((x.lt.xa(j)).or.(x.gt.xa(j+1))) then
938       if (j.ne.nx) then
939          write(errMSG,*) "EAM_splint:",x," x is outside bounding range"
940          call handleError(routineName,errMSG)
941       endif
942    endif
943
944    del = xa(j+1) - x
945    h = xa(j+1) - xa(j)
946
947    a = del / h
948    b = 1.0E0_DP - a
949    c = a*(a*a - 1.0E0_DP)*h*h/6.0E0_DP
950    d = b*(b*b - 1.0E0_DP)*h*h/6.0E0_DP
951
952    y = a*ya(j) + b*ya(j+1) + c*yppa(j) + d*yppa(j+1)
953
954    dy = (ya(j+1)-ya(j))/h &
955         - (3.0E0_DP*a*a - 1.0E0_DP)*h*yppa(j)/6.0E0_DP &
956         + (3.0E0_DP*b*b - 1.0E0_DP)*h*yppa(j+1)/6.0E0_DP
957
958
959    d2y = a*yppa(j) + b*yppa(j+1)
960
961
962  end subroutine eam_splint
963
964
965  subroutine eam_spline(nx, xa, ya, yppa, yp1, ypn, boundary)
966
967
968    ! yp1 and ypn are the first derivatives of y at the two endpoints
969    ! if boundary is 'L' the lower derivative is used
970    ! if boundary is 'U' the upper derivative is used
971    ! if boundary is 'B' then both derivatives are used
972    ! if boundary is anything else, then both derivatives are assumed to be 0
973
974    integer :: nx, i, k, max_array_size
975
976    real( kind = DP ), dimension(:)        :: xa
977    real( kind = DP ), dimension(:)        :: ya
978    real( kind = DP ), dimension(:)        :: yppa
979    real( kind = DP ), dimension(size(xa)) :: u
980    real( kind = DP ) :: yp1,ypn,un,qn,sig,p
981    character(len=*) :: boundary
982
983    ! make sure the sizes match
984    if ((nx /= size(xa)) .or. (nx /= size(ya))) then
985       call handleWarning("EAM_SPLINE","Array size mismatch")
986    end if
987
988    if ((boundary.eq.'l').or.(boundary.eq.'L').or. &
989         (boundary.eq.'b').or.(boundary.eq.'B')) then
990       yppa(1) = -0.5E0_DP
991       u(1) = (3.0E0_DP/(xa(2)-xa(1)))*((ya(2)-&
992            ya(1))/(xa(2)-xa(1))-yp1)
993    else
994       yppa(1) = 0.0E0_DP
995       u(1)  = 0.0E0_DP
996    endif
997
998    do i = 2, nx - 1
999       sig = (xa(i) - xa(i-1)) / (xa(i+1) - xa(i-1))
1000       p = sig * yppa(i-1) + 2.0E0_DP
1001       yppa(i) = (sig - 1.0E0_DP) / p
1002       u(i) = (6.0E0_DP*((ya(i+1)-ya(i))/(xa(i+1)-xa(i)) - &
1003            (ya(i)-ya(i-1))/(xa(i)-xa(i-1)))/ &
1004            (xa(i+1)-xa(i-1)) - sig * u(i-1))/p
1005    enddo
1006
1007    if ((boundary.eq.'u').or.(boundary.eq.'U').or. &
1008         (boundary.eq.'b').or.(boundary.eq.'B')) then
1009       qn = 0.5E0_DP
1010       un = (3.0E0_DP/(xa(nx)-xa(nx-1)))* &
1011            (ypn-(ya(nx)-ya(nx-1))/(xa(nx)-xa(nx-1)))
1012    else
1013       qn = 0.0E0_DP
1014       un = 0.0E0_DP
1015    endif
1016
1017    yppa(nx)=(un-qn*u(nx-1))/(qn*yppa(nx-1)+1.0E0_DP)
1018
1019    do k = nx-1, 1, -1
1020       yppa(k)=yppa(k)*yppa(k+1)+u(k)
1021    enddo
1022
1023  end subroutine eam_spline
1024
679   end module eam

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines