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

Comparing trunk/OOPSE-4/src/UseTheForce/DarkSide/suttonchen.F90 (file contents):
Revision 2406 by chuckv, Tue Nov 1 23:32:25 2005 UTC vs.
Revision 2430 by chuckv, Mon Nov 14 22:20:35 2005 UTC

# Line 63 | Line 63 | module suttonchen
63    integer, save :: SC_Mixing_Policy
64    real(kind = dp), save :: SC_rcut
65    logical, save :: haveRcut = .false.
66 +  logical, save :: haveMixingMap = .false.
67 +  logical, save :: useGeometricDistanceMixing = .false.
68  
69 +
70 +
71 +
72    character(len = statusMsgSize) :: errMesg
73 <  integer :: eam_err
73 >  integer :: sc_err
74  
75    character(len = 200) :: errMsg
76    character(len=*), parameter :: RoutineName =  "Sutton-Chen MODULE"
# Line 81 | Line 86 | module suttonchen
86       real(kind=dp)     :: n
87       real(kind=dp)     :: alpha
88       real(kind=dp)     :: epsilon
89 +     real(kind=dp)     :: sc_rcut
90    end type SCtype
91  
92  
93    !! Arrays for derivatives used in force calculation
88  real( kind = dp), dimension(:), allocatable :: frho
94    real( kind = dp), dimension(:), allocatable :: rho
95 <
95 >  real( kind = dp), dimension(:), allocatable :: frho
96    real( kind = dp), dimension(:), allocatable :: dfrhodrho
92  real( kind = dp), dimension(:), allocatable :: d2frhodrhodrho
97  
98  
99 +
100    !! Arrays for MPI storage
101   #ifdef IS_MPI
102    real( kind = dp),save, dimension(:), allocatable :: dfrhodrho_col
# Line 101 | Line 106 | module suttonchen
106    real( kind = dp),save, dimension(:), allocatable :: rho_row
107    real( kind = dp),save, dimension(:), allocatable :: rho_col
108    real( kind = dp),save, dimension(:), allocatable :: rho_tmp
104  real( kind = dp),save, dimension(:), allocatable :: d2frhodrhodrho_col
105  real( kind = dp),save, dimension(:), allocatable :: d2frhodrhodrho_row
109   #endif
110  
111    type, private :: SCTypeList
# Line 121 | Line 124 | module suttonchen
124   type :: MixParameters
125       real(kind=DP) :: alpha
126       real(kind=DP) :: epsilon
127 <     real(kind=dp) :: sigma6
127 >     real(kind=DP) :: m
128 >     real(Kind=DP) :: n
129 >     real(kind=DP) :: vpair_pot
130       real(kind=dp) :: rCut
126     real(kind=dp) :: delta
131       logical       :: rCutWasSet = .false.
132 <     logical       :: shiftedPot
129 <     logical       :: isSoftCore = .false.
132 >
133    end type MixParameters
134  
135    type(MixParameters), dimension(:,:), allocatable :: MixingMap
136  
137  
138  
136  public :: init_SC_FF
139    public :: setCutoffSC
140    public :: do_SC_pair
141    public :: newSCtype
# Line 141 | Line 143 | module suttonchen
143    public :: clean_SC
144    public :: destroySCtypes
145    public :: getSCCut
146 + ! public :: setSCDefaultCutoff
147 + ! public :: setSCUniformCutoff
148 +  public :: useGeometricMixing
149  
150   contains
151  
152  
153 <  subroutine newSCtype(c,m,n,alpha,epsilon,c_ident,status)
154 <    real (kind = dp )                      :: lattice_constant
155 <    integer                                :: eam_nrho
156 <    real (kind = dp )                      :: eam_drho
157 <    integer                                :: eam_nr
158 <    real (kind = dp )                      :: eam_dr
159 <    real (kind = dp )                      :: rcut
160 <    real (kind = dp ), dimension(eam_nr)   :: eam_Z_r
156 <    real (kind = dp ), dimension(eam_nr)   :: eam_rho_r
157 <    real (kind = dp ), dimension(eam_nrho) :: eam_F_rho
153 >  subroutine newSCtype(c_ident,c,m,n,alpha,epsilon,status)
154 >    real (kind = dp )                      :: c ! Density Scaling
155 >    real (kind = dp )                      :: m ! Density Exponent
156 >    real (kind = dp )                      :: n ! Pair Potential Exponent
157 >    real (kind = dp )                      :: alpha ! Length Scaling
158 >    real (kind = dp )                      :: epsilon ! Energy Scaling
159 >
160 >
161      integer                                :: c_ident
162      integer                                :: status
163  
164 <    integer                                :: nAtypes,nEAMTypes,myATID
164 >    integer                                :: nAtypes,nSCTypes,myATID
165      integer                                :: maxVals
166      integer                                :: alloc_stat
167      integer                                :: current
# Line 168 | Line 171 | contains
171  
172  
173      !! Assume that atypes has already been set and get the total number of types in atypes
171    !! Also assume that every member of atypes is a EAM model.
174  
175  
176      ! check to see if this is the first time into
177 <    if (.not.associated(EAMList%EAMParams)) then
178 <       call getMatchingElementList(atypes, "is_EAM", .true., nEAMtypes, MatchList)
179 <       EAMList%n_eam_types = nEAMtypes
180 <       allocate(EAMList%EAMParams(nEAMTypes))
177 >    if (.not.associated(SCList%SCTypes)) then
178 >       call getMatchingElementList(atypes, "is_SuttonChen", .true., nSCtypes, MatchList)
179 >       SCList%nSCtypes = nSCtypes
180 >       allocate(SCList%SCTypes(nSCTypes))
181         nAtypes = getSize(atypes)
182 <       allocate(EAMList%atidToEAMType(nAtypes))
182 >       allocate(SCList%atidToSCType(nAtypes))
183      end if
184  
185 <    EAMList%currentAddition = EAMList%currentAddition + 1
186 <    current = EAMList%currentAddition
185 >    SCList%currentSCType = SCList%currentSCType + 1
186 >    current = SCList%currentSCType
187  
188      myATID =  getFirstMatchingElement(atypes, "c_ident", c_ident)
189 <    EAMList%atidToEAMType(myATID) = current
189 >    SCList%atidToSCType(myATID) = current
190  
189    call allocate_EAMType(eam_nrho,eam_nr,EAMList%EAMParams(current),stat=alloc_stat)
190    if (alloc_stat /= 0) then
191       status = -1
192       return
193    end if
191  
192    
193 <    EAMList%EAMParams(current)%eam_atype    = c_ident
194 <    EAMList%EAMParams(current)%eam_lattice  = lattice_constant
195 <    EAMList%EAMParams(current)%eam_nrho     = eam_nrho
196 <    EAMList%EAMParams(current)%eam_drho     = eam_drho
197 <    EAMList%EAMParams(current)%eam_nr       = eam_nr
198 <    EAMList%EAMParams(current)%eam_dr       = eam_dr
199 <    EAMList%EAMParams(current)%eam_rcut     = rcut
203 <    EAMList%EAMParams(current)%eam_Z_r      = eam_Z_r
204 <    EAMList%EAMParams(current)%eam_rho_r    = eam_rho_r
205 <    EAMList%EAMParams(current)%eam_F_rho    = eam_F_rho
193 >    SCList%SCTypes(current)%atid         = c_ident
194 >    SCList%SCTypes(current)%alpha        = alpha
195 >    SCList%SCTypes(current)%c            = c
196 >    SCList%SCTypes(current)%m            = m
197 >    SCList%SCTypes(current)%n            = n
198 >    SCList%SCTypes(current)%epsilon      = epsilon
199 >  end subroutine newSCtype
200  
201 <  end subroutine newEAMtype
201 >  
202 >  subroutine destroySCTypes()
203 >    if (associated(SCList%SCtypes)) then
204 >       deallocate(SCList%SCTypes)
205 >       SCList%SCTypes=>null()
206 >    end if
207 >    if (associated(SCList%atidToSCtype)) then
208 >       deallocate(SCList%atidToSCtype)
209 >       SCList%atidToSCtype=>null()
210 >    end if
211  
212  
213 <  ! kills all eam types entered and sets simulation to uninitalized
211 <  subroutine destroyEAMtypes()
212 <    integer :: i
213 <    type(EAMType), pointer :: tempEAMType=>null()
213 >  end subroutine destroySCTypes
214  
215    do i = 1, EAMList%n_eam_types
216       tempEAMType => eamList%EAMParams(i)
217       call deallocate_EAMType(tempEAMType)
218    end do
219    if(associated( eamList%EAMParams)) deallocate( eamList%EAMParams)
220    eamList%EAMParams => null()
215  
216 <    eamList%n_eam_types = 0
217 <    eamList%currentAddition = 0
224 <
225 <  end subroutine destroyEAMtypes
226 <
227 <  function getEAMCut(atomID) result(cutValue)
216 >
217 >  function getSCCut(atomID) result(cutValue)
218      integer, intent(in) :: atomID
219 <    integer :: eamID
219 >    integer :: scID
220      real(kind=dp) :: cutValue
221      
222 <    eamID = EAMList%atidToEAMType(atomID)
223 <    cutValue = EAMList%EAMParams(eamID)%eam_rcut
224 <  end function getEAMCut
222 >    scID = SCList%atidToSCType(atomID)
223 >    cutValue = SCList%SCTypes(scID)%sc_rcut
224 >  end function getSCCut
225  
236  subroutine init_EAM_FF(status)
237    integer :: status
238    integer :: i,j
239    real(kind=dp) :: current_rcut_max
240    integer :: alloc_stat
241    integer :: number_r, number_rho
226  
227  
228 <    status = 0
229 <    if (EAMList%currentAddition == 0) then
230 <       call handleError("init_EAM_FF","No members in EAMList")
231 <       status = -1
228 >
229 >  subroutine createMixingMap()
230 >    integer :: nSCtypes, i, j
231 >    real ( kind = dp ) :: e1, e2,m1,m2,alpha1,alpha2,n1,n2
232 >    real ( kind = dp ) :: rcut6, tp6, tp12
233 >    logical :: isSoftCore1, isSoftCore2, doShift
234 >
235 >    if (SCList%currentSCtype == 0) then
236 >       call handleError("SuttonChen", "No members in SCMap")
237         return
238      end if
239  
240 +    nSCtypes = SCList%nSCtypes
241  
242 <    do i = 1, EAMList%currentAddition
242 >    if (.not. allocated(MixingMap)) then
243 >       allocate(MixingMap(nSCtypes, nSCtypes))
244 >    endif
245  
246 <       ! Build array of r values
246 >    do i = 1, nSCtypes
247  
248 <       do j = 1,EAMList%EAMParams(i)%eam_nr
249 <          EAMList%EAMParams(i)%eam_rvals(j) = &
250 <               real(j-1,kind=dp)* &
251 <               EAMList%EAMParams(i)%eam_dr
260 <       end do
261 <       ! Build array of rho values
262 <       do j = 1,EAMList%EAMParams(i)%eam_nrho
263 <          EAMList%EAMParams(i)%eam_rhovals(j) = &
264 <               real(j-1,kind=dp)* &
265 <               EAMList%EAMParams(i)%eam_drho
266 <       end do
267 <       ! convert from eV to kcal / mol:
268 <       EAMList%EAMParams(i)%eam_F_rho = EAMList%EAMParams(i)%eam_F_rho * 23.06054E0_DP
248 >       e1 = SCList%SCtypes(i)%epsilon
249 >       m1 = SCList%SCtypes(i)%m
250 >       n1 = SCList%SCtypes(i)%n
251 >       alpha1 = SCList%SCtypes(i)%alpha
252  
253 <       ! precompute the pair potential and get it into kcal / mol:
254 <       EAMList%EAMParams(i)%eam_phi_r(1) = 0.0E0_DP
272 <       do j = 2, EAMList%EAMParams(i)%eam_nr
273 <          EAMList%EAMParams(i)%eam_phi_r(j) = (EAMList%EAMParams(i)%eam_Z_r(j)**2)/EAMList%EAMParams(i)%eam_rvals(j)
274 <          EAMList%EAMParams(i)%eam_phi_r(j) =  EAMList%EAMParams(i)%eam_phi_r(j)*331.999296E0_DP
275 <       enddo
276 <    end do
253 >       do j = i, nSCtypes
254 >          
255  
256 +          e2 = SCList%SCtypes(j)%epsilon
257 +          m2 = SCList%SCtypes(j)%m
258 +          n2 = SCList%SCtypes(j)%n
259 +          alpha2 = SCList%SCtypes(j)%alpha
260  
261 <    do i = 1,  EAMList%currentAddition
262 <       number_r   = EAMList%EAMParams(i)%eam_nr
263 <       number_rho = EAMList%EAMParams(i)%eam_nrho
264 <
265 <       call eam_spline(number_r, EAMList%EAMParams(i)%eam_rvals, &
284 <            EAMList%EAMParams(i)%eam_rho_r, &
285 <            EAMList%EAMParams(i)%eam_rho_r_pp, &
286 <            0.0E0_DP, 0.0E0_DP, 'N')
287 <       call eam_spline(number_r, EAMList%EAMParams(i)%eam_rvals, &
288 <            EAMList%EAMParams(i)%eam_Z_r, &
289 <            EAMList%EAMParams(i)%eam_Z_r_pp, &
290 <            0.0E0_DP, 0.0E0_DP, 'N')
291 <       call eam_spline(number_rho, EAMList%EAMParams(i)%eam_rhovals, &
292 <            EAMList%EAMParams(i)%eam_F_rho, &
293 <            EAMList%EAMParams(i)%eam_F_rho_pp, &
294 <            0.0E0_DP, 0.0E0_DP, 'N')
295 <       call eam_spline(number_r, EAMList%EAMParams(i)%eam_rvals, &
296 <            EAMList%EAMParams(i)%eam_phi_r, &
297 <            EAMList%EAMParams(i)%eam_phi_r_pp, &
298 <            0.0E0_DP, 0.0E0_DP, 'N')
299 <    enddo
261 >          if (useGeometricDistanceMixing) then
262 >             MixingMap(i,j)%alpha = sqrt(alpha1 * alpha2) !SC formulation
263 >          else
264 >             MixingMap(i,j)%alpha = 0.5_dp * (alpha1 + alpha2) ! Goddard formulation
265 >          endif
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
267 >          MixingMap(i,j)%epsilon = sqrt(e1 * e2)
268 >          MixingMap(i,j)%m = 0.5_dp*(m1+m2)
269 >          MixingMap(i,j)%n = 0.5_dp*(n1+n2)
270 >          MixingMap(i,j)%alpha = 0.5_dp*(alpha1+alpha2)
271 >          MixingMap(i,j)%rcut = 2.0_dp *MixingMap(i,j)%alpha
272 >          MixingMap(i,j)%vpair_pot = MixingMap(i,j)%epsilon* &
273 >               (MixingMap(i,j)%alpha/MixingMap(i,j)%rcut)**MixingMap(i,j)%n
274 >          if (i.ne.j) then
275 >             MixingMap(j,i)%epsilon    = MixingMap(i,j)%epsilon
276 >             MixingMap(j,i)%m          = MixingMap(i,j)%m
277 >             MixingMap(j,i)%n          = MixingMap(i,j)%n
278 >             MixingMap(j,i)%alpha      = MixingMap(i,j)%alpha
279 >             MixingMap(j,i)%rcut = MixingMap(i,j)%rcut
280 >             MixingMap(j,i)%vpair_pot = MixingMap(i,j)%vpair_pot
281 >          endif
282 >       enddo
283 >    enddo
284 >    
285 >    haveMixingMap = .true.
286 >    
287 >  end subroutine createMixingMap
288 >  
289  
307    !       EAM_rcut = current_rcut_max
308    !       EAM_rcut_orig = current_rcut_max
309    !       do i = 1, EAMList%currentAddition
310    !          EAMList%EAMParam(i)s%eam_atype_map(eam_atype(i)) = i
311    !       end do
312    !! Allocate arrays for force calculation
313
314    call allocateEAM(alloc_stat)
315    if (alloc_stat /= 0 ) then
316       write(*,*) "allocateEAM failed"
317       status = -1
318       return
319    endif
320
321  end subroutine init_EAM_FF
322
290    !! routine checks to see if array is allocated, deallocates array if allocated
291    !! and then creates the array to the required size
292 <  subroutine allocateEAM(status)
292 >  subroutine allocateSC(status)
293      integer, intent(out) :: status
294  
295   #ifdef IS_MPI
# Line 338 | Line 305 | contains
305      nAtomsInCol = getNatomsInCol(plan_atom_col)
306   #endif
307  
308 +
309 +
310      if (allocated(frho)) deallocate(frho)
311      allocate(frho(nlocal),stat=alloc_stat)
312 <    if (alloc_stat /= 0) then
312 >    if (alloc_stat /= 0) then
313         status = -1
314         return
315      end if
316 +
317      if (allocated(rho)) deallocate(rho)
318      allocate(rho(nlocal),stat=alloc_stat)
319      if (alloc_stat /= 0) then
# Line 358 | Line 328 | contains
328         return
329      end if
330  
361    if (allocated(d2frhodrhodrho)) deallocate(d2frhodrhodrho)
362    allocate(d2frhodrhodrho(nlocal),stat=alloc_stat)
363    if (alloc_stat /= 0) then
364       status = -1
365       return
366    end if
367
331   #ifdef IS_MPI
332  
333      if (allocated(rho_tmp)) deallocate(rho_tmp)
# Line 393 | Line 356 | contains
356         status = -1
357         return
358      end if
396    if (allocated(d2frhodrhodrho_row)) deallocate(d2frhodrhodrho_row)
397    allocate(d2frhodrhodrho_row(nAtomsInRow),stat=alloc_stat)
398    if (alloc_stat /= 0) then
399       status = -1
400       return
401    end if
359  
360  
361      ! Now do column arrays
# Line 421 | Line 378 | contains
378         status = -1
379         return
380      end if
424    if (allocated(d2frhodrhodrho_col)) deallocate(d2frhodrhodrho_col)
425    allocate(d2frhodrhodrho_col(nAtomsInCol),stat=alloc_stat)
426    if (alloc_stat /= 0) then
427       status = -1
428       return
429    end if
381  
382   #endif
383  
384 <  end subroutine allocateEAM
384 >  end subroutine allocateSC
385  
386    !! C sets rcut to be the largest cutoff of any atype
387    !! present in this simulation. Doesn't include all atypes
388    !! sim knows about, just those in the simulation.
389 <  subroutine setCutoffEAM(rcut, status)
389 >  subroutine setCutoffSC(rcut, status)
390      real(kind=dp) :: rcut
391      integer :: status
392      status = 0
393  
394 <    EAM_rcut = rcut
394 >    SC_rcut = rcut
395  
396 <  end subroutine setCutoffEAM
396 >  end subroutine setCutoffSC
397  
398 +  subroutine useGeometricMixing()
399 +    useGeometricDistanceMixing = .true.
400 +    haveMixingMap = .false.
401 +    return
402 +  end subroutine useGeometricMixing
403 +  
404  
405  
449  subroutine clean_EAM()
406  
407 +
408 +
409 +
410 +
411 +
412 +  subroutine clean_SC()
413 +
414      ! clean non-IS_MPI first
415      frho = 0.0_dp
416      rho  = 0.0_dp
# Line 462 | Line 425 | contains
425      dfrhodrho_row = 0.0_dp
426      dfrhodrho_col = 0.0_dp
427   #endif
428 <  end subroutine clean_EAM
428 >  end subroutine clean_SC
429  
430  
431  
469  subroutine allocate_EAMType(eam_n_rho,eam_n_r,thisEAMType,stat)
470    integer, intent(in)          :: eam_n_rho
471    integer, intent(in)          :: eam_n_r
472    type (EAMType)               :: thisEAMType
473    integer, optional   :: stat
474    integer             :: alloc_stat
475
476
477
478    if (present(stat)) stat = 0
479
480    allocate(thisEAMType%eam_rvals(eam_n_r),stat=alloc_stat)  
481    if (alloc_stat /= 0 ) then
482       if (present(stat)) stat = -1
483       return
484    end if
485    allocate(thisEAMType%eam_rhovals(eam_n_rho),stat=alloc_stat)  
486    if (alloc_stat /= 0 ) then
487       if (present(stat)) stat = -1
488       return
489    end if
490    allocate(thisEAMType%eam_F_rho(eam_n_rho),stat=alloc_stat)  
491    if (alloc_stat /= 0 ) then
492       if (present(stat)) stat = -1
493       return
494    end if
495    allocate(thisEAMType%eam_Z_r(eam_n_r),stat=alloc_stat)        
496    if (alloc_stat /= 0 ) then
497       if (present(stat)) stat = -1
498       return
499    end if
500    allocate(thisEAMType%eam_rho_r(eam_n_r),stat=alloc_stat)      
501    if (alloc_stat /= 0 ) then
502       if (present(stat)) stat = -1
503       return
504    end if
505    allocate(thisEAMType%eam_phi_r(eam_n_r),stat=alloc_stat)      
506    if (alloc_stat /= 0 ) then
507       if (present(stat)) stat = -1
508       return
509    end if
510    allocate(thisEAMType%eam_F_rho_pp(eam_n_rho),stat=alloc_stat)  
511    if (alloc_stat /= 0 ) then
512       if (present(stat)) stat = -1
513       return
514    end if
515    allocate(thisEAMType%eam_Z_r_pp(eam_n_r),stat=alloc_stat)  
516    if (alloc_stat /= 0 ) then
517       if (present(stat)) stat = -1
518       return
519    end if
520    allocate(thisEAMType%eam_rho_r_pp(eam_n_r),stat=alloc_stat)  
521    if (alloc_stat /= 0 ) then
522       if (present(stat)) stat = -1
523       return
524    end if
525    allocate(thisEAMType%eam_phi_r_pp(eam_n_r),stat=alloc_stat)
526    if (alloc_stat /= 0 ) then
527       if (present(stat)) stat = -1
528       return
529    end if
530
531
532  end subroutine allocate_EAMType
533
534
535  subroutine deallocate_EAMType(thisEAMType)
536    type (EAMtype), pointer :: thisEAMType
537
538    ! free Arrays in reverse order of allocation...
539    if(associated(thisEAMType%eam_phi_r_pp)) deallocate(thisEAMType%eam_phi_r_pp)      
540    if(associated(thisEAMType%eam_rho_r_pp)) deallocate(thisEAMType%eam_rho_r_pp)  
541    if(associated(thisEAMType%eam_Z_r_pp)) deallocate(thisEAMType%eam_Z_r_pp)  
542    if(associated(thisEAMType%eam_F_rho_pp)) deallocate(thisEAMType%eam_F_rho_pp)  
543    if(associated(thisEAMType%eam_phi_r)) deallocate(thisEAMType%eam_phi_r)      
544    if(associated(thisEAMType%eam_rho_r)) deallocate(thisEAMType%eam_rho_r)      
545    if(associated(thisEAMType%eam_Z_r)) deallocate(thisEAMType%eam_Z_r)  
546    if(associated(thisEAMType%eam_F_rho)) deallocate(thisEAMType%eam_F_rho)
547    if(associated(thisEAMType%eam_rhovals)) deallocate(thisEAMType%eam_rhovals)
548    if(associated(thisEAMType%eam_rvals)) deallocate(thisEAMType%eam_rvals)
549
550  end subroutine deallocate_EAMType
551
432    !! Calculates rho_r
433 <  subroutine calc_eam_prepair_rho(atom1,atom2,d,r,rijsq)
433 >  subroutine calc_sc_prepair_rho(atom1,atom2,d,r,rijsq)
434      integer :: atom1,atom2
435      real(kind = dp), dimension(3) :: d
436      real(kind = dp), intent(inout)               :: r
# Line 561 | Line 441 | contains
441      real(kind = dp) :: rho_j_at_i
442  
443      ! we don't use the derivatives, dummy variables
444 <    real( kind = dp) :: drho,d2rho
445 <    integer :: eam_err
444 >    real( kind = dp) :: drho
445 >    integer :: sc_err
446      
447      integer :: atid1,atid2 ! Global atid    
448      integer :: myid_atom1 ! EAM atid
# Line 582 | Line 462 | contains
462      Atid2 = Atid(Atom2)
463   #endif
464  
465 <    Myid_atom1 = Eamlist%atidtoeamtype(Atid1)
466 <    Myid_atom2 = Eamlist%atidtoeamtype(Atid2)
465 >    Myid_atom1 = SCList%atidtoSCtype(Atid1)
466 >    Myid_atom2 = SCList%atidtoSCtype(Atid2)
467  
588    if (r.lt.EAMList%EAMParams(myid_atom1)%eam_rcut) then
468  
469  
470 <
471 <       call eam_splint(EAMList%EAMParams(myid_atom1)%eam_nr, &
472 <            EAMList%EAMParams(myid_atom1)%eam_rvals, &
594 <            EAMList%EAMParams(myid_atom1)%eam_rho_r, &
595 <            EAMList%EAMParams(myid_atom1)%eam_rho_r_pp, &
596 <            r, rho_i_at_j,drho,d2rho)
597 <
470 >       rho_i_at_j = (MixingMap(Myid_atom1,Myid_atom2)%alpha/r)&
471 >            **MixingMap(Myid_atom1,Myid_atom2)%m
472 >       rho_j_at_i = rho_i_at_j
473  
599
474   #ifdef  IS_MPI
475         rho_col(atom2) = rho_col(atom2) + rho_i_at_j
602 #else
603       rho(atom2) = rho(atom2) + rho_i_at_j
604 #endif
605             ! write(*,*) atom1,atom2,r,rho_i_at_j
606    endif
607
608    if (r.lt.EAMList%EAMParams(myid_atom2)%eam_rcut) then
609       call eam_splint(EAMList%EAMParams(myid_atom2)%eam_nr, &
610            EAMList%EAMParams(myid_atom2)%eam_rvals, &
611            EAMList%EAMParams(myid_atom2)%eam_rho_r, &
612            EAMList%EAMParams(myid_atom2)%eam_rho_r_pp, &
613            r, rho_j_at_i,drho,d2rho)
614
615
616
617
618 #ifdef  IS_MPI
476         rho_row(atom1) = rho_row(atom1) + rho_j_at_i
477   #else
478 +       rho(atom2) = rho(atom2) + rho_i_at_j
479         rho(atom1) = rho(atom1) + rho_j_at_i
480   #endif
623    endif
481  
482 +  end subroutine calc_sc_prepair_rho
483  
484  
485 <
486 <
629 <
630 <  end subroutine calc_eam_prepair_rho
631 <
632 <
633 <
634 <
635 <  !! Calculate the functional F(rho) for all local atoms
636 <  subroutine calc_eam_preforce_Frho(nlocal,pot)
485 > !! Calculate the rho_a for all local atoms
486 >  subroutine calc_sc_preforce_Frho(nlocal,pot)
487      integer :: nlocal
488      real(kind=dp) :: pot
489      integer :: i,j
490      integer :: atom
491      real(kind=dp) :: U,U1,U2
492      integer :: atype1
493 <    integer :: me,atid1
494 <    integer :: n_rho_points
493 >    integer :: atid1
494 >    integer :: myid
495  
496  
497      cleanme = .true.
498      !! Scatter the electron density from  pre-pair calculation back to local atoms
499   #ifdef IS_MPI
500 <    call scatter(rho_row,rho,plan_atom_row,eam_err)
501 <    if (eam_err /= 0 ) then
500 >    call scatter(rho_row,rho,plan_atom_row,sc_err)
501 >    if (sc_err /= 0 ) then
502         write(errMsg,*) " Error scattering rho_row into rho"
503         call handleError(RoutineName,errMesg)
504      endif
505 <    call scatter(rho_col,rho_tmp,plan_atom_col,eam_err)
506 <    if (eam_err /= 0 ) then
505 >    call scatter(rho_col,rho_tmp,plan_atom_col,sc_err)
506 >    if (sc_err /= 0 ) then
507         write(errMsg,*) " Error scattering rho_col into rho"
508         call handleError(RoutineName,errMesg)
509 +
510      endif
511  
512      rho(1:nlocal) = rho(1:nlocal) + rho_tmp(1:nlocal)
# Line 663 | Line 514 | contains
514  
515  
516  
517 <    !! Calculate F(rho) and derivative
517 >    !! Calculate F(rho) and derivative
518      do atom = 1, nlocal
519 <       atid1 = atid(atom)
520 <       me = eamList%atidToEAMtype(atid1)
521 <       n_rho_points = EAMList%EAMParams(me)%eam_nrho
671 <       !  Check to see that the density is not greater than the larges rho we have calculated
672 <       if (rho(atom) < EAMList%EAMParams(me)%eam_rhovals(n_rho_points)) then
673 <          call eam_splint(n_rho_points, &
674 <               EAMList%EAMParams(me)%eam_rhovals, &
675 <               EAMList%EAMParams(me)%eam_f_rho, &
676 <               EAMList%EAMParams(me)%eam_f_rho_pp, &
677 <               rho(atom), & ! Actual Rho
678 <               u, u1, u2)
679 <       else
680 <          ! Calculate F(rho with the largest available rho value
681 <          call eam_splint(n_rho_points, &
682 <               EAMList%EAMParams(me)%eam_rhovals, &
683 <               EAMList%EAMParams(me)%eam_f_rho, &
684 <               EAMList%EAMParams(me)%eam_f_rho_pp, &
685 <               EAMList%EAMParams(me)%eam_rhovals(n_rho_points), & ! Largest rho
686 <               u,u1,u2)
687 <       end if
519 >       Myid = SCList%atidtoSctype(Atid(atom))
520 >       frho(atom) = -SCList%SCTypes(Myid)%c * &
521 >            SCList%SCTypes(Myid)%epsilon * sqrt(rho(i))
522  
523 <
690 <       frho(atom) = u
691 <       dfrhodrho(atom) = u1
692 <       d2frhodrhodrho(atom) = u2
523 >       dfrhodrho(atom) = 0.5_dp*frho(atom)/rho(atom)
524         pot = pot + u
694
525      enddo
526  
697
698
527   #ifdef IS_MPI
528      !! communicate f(rho) and derivatives back into row and column arrays
529 <    call gather(frho,frho_row,plan_atom_row, eam_err)
530 <    if (eam_err /=  0) then
529 >    call gather(frho,frho_row,plan_atom_row, sc_err)
530 >    if (sc_err /=  0) then
531         call handleError("cal_eam_forces()","MPI gather frho_row failure")
532      endif
533 <    call gather(dfrhodrho,dfrhodrho_row,plan_atom_row, eam_err)
534 <    if (eam_err /=  0) then
533 >    call gather(dfrhodrho,dfrhodrho_row,plan_atom_row, sc_err)
534 >    if (sc_err /=  0) then
535         call handleError("cal_eam_forces()","MPI gather dfrhodrho_row failure")
536      endif
537 <    call gather(frho,frho_col,plan_atom_col, eam_err)
538 <    if (eam_err /=  0) then
537 >    call gather(frho,frho_col,plan_atom_col, sc_err)
538 >    if (sc_err /=  0) then
539         call handleError("cal_eam_forces()","MPI gather frho_col failure")
540      endif
541 <    call gather(dfrhodrho,dfrhodrho_col,plan_atom_col, eam_err)
542 <    if (eam_err /=  0) then
541 >    call gather(dfrhodrho,dfrhodrho_col,plan_atom_col, sc_err)
542 >    if (sc_err /=  0) then
543         call handleError("cal_eam_forces()","MPI gather dfrhodrho_col failure")
544      endif
717
718
719
720
721
722    if (nmflag) then
723       call gather(d2frhodrhodrho,d2frhodrhodrho_row,plan_atom_row)
724       call gather(d2frhodrhodrho,d2frhodrhodrho_col,plan_atom_col)
725    endif
545   #endif
546 +    
547 +    
548 +  end subroutine calc_sc_preforce_Frho
549  
550  
551 <  end subroutine calc_eam_preforce_Frho
552 <
731 <
732 <
733 <
734 <  !! Does EAM pairwise Force calculation.  
735 <  subroutine do_eam_pair(atom1, atom2, d, rij, r2, sw, vpair, fpair, &
551 >  !! Does Sutton-Chen  pairwise Force calculation.  
552 >  subroutine do_sc_pair(atom1, atom2, d, rij, r2, sw, vpair, fpair, &
553         pot, f, do_pot)
554      !Arguments    
555      integer, intent(in) ::  atom1, atom2
# Line 745 | Line 562 | contains
562      logical, intent(in) :: do_pot
563  
564      real( kind = dp ) :: drdx,drdy,drdz
565 <    real( kind = dp ) :: d2
566 <    real( kind = dp ) :: phab,pha,dvpdr,d2vpdrdr
750 <    real( kind = dp ) :: rha,drha,d2rha, dpha
751 <    real( kind = dp ) :: rhb,drhb,d2rhb, dphb
565 >    real( kind = dp ) :: dvpdr
566 >    real( kind = dp ) :: drhodr
567      real( kind = dp ) :: dudr
568 <    real( kind = dp ) :: rci,rcj
568 >    real( kind = dp ) :: rcij
569      real( kind = dp ) :: drhoidr,drhojdr
755    real( kind = dp ) :: d2rhoidrdr
756    real( kind = dp ) :: d2rhojdrdr
570      real( kind = dp ) :: Fx,Fy,Fz
571      real( kind = dp ) :: r,d2pha,phb,d2phb
572 <
572 >    real( kind = dp ) :: pot_temp,vptmp
573 >    real( kind = dp ) :: epsilonij,aij,nij,mij,vcij
574      integer :: id1,id2
575      integer  :: mytype_atom1
576      integer  :: mytype_atom2
# Line 765 | Line 579 | contains
579  
580      ! write(*,*) "Frho: ", Frho(atom1)
581  
582 <    phab = 0.0E0_DP
582 >
583      dvpdr = 0.0E0_DP
770    d2vpdrdr = 0.0E0_DP
584  
772    if (rij .lt. EAM_rcut) then
585  
586   #ifdef IS_MPI
587         atid1 = atid_row(atom1)
# Line 779 | Line 591 | contains
591         atid2 = atid(atom2)
592   #endif
593  
594 <       mytype_atom1 = EAMList%atidToEAMType(atid1)
595 <       mytype_atom2 = EAMList%atidTOEAMType(atid2)
594 >       mytype_atom1 = SCList%atidToSCType(atid1)
595 >       mytype_atom2 = SCList%atidTOSCType(atid2)
596  
785
786       ! get cutoff for atom 1
787       rci = EAMList%EAMParams(mytype_atom1)%eam_rcut
788       ! get type specific cutoff for atom 2
789       rcj = EAMList%EAMParams(mytype_atom2)%eam_rcut
790
597         drdx = d(1)/rij
598         drdy = d(2)/rij
599         drdz = d(3)/rij
600  
601 <       if (rij.lt.rci) then
602 <          call eam_splint(EAMList%EAMParams(mytype_atom1)%eam_nr, &
603 <               EAMList%EAMParams(mytype_atom1)%eam_rvals, &
604 <               EAMList%EAMParams(mytype_atom1)%eam_rho_r, &
605 <               EAMList%EAMParams(mytype_atom1)%eam_rho_r_pp, &
606 <               rij, rha,drha,d2rha)
801 <          !! Calculate Phi(r) for atom1.
802 <          call eam_splint(EAMList%EAMParams(mytype_atom1)%eam_nr, &
803 <               EAMList%EAMParams(mytype_atom1)%eam_rvals, &
804 <               EAMList%EAMParams(mytype_atom1)%eam_phi_r, &
805 <               EAMList%EAMParams(mytype_atom1)%eam_phi_r_pp, &
806 <               rij, pha,dpha,d2pha)
807 <       endif
601 >                
602 >       epsilonij = MixingMap(mytype_atom1,mytype_atom2)%epsilon
603 >       aij       = MixingMap(mytype_atom1,mytype_atom2)%alpha
604 >       nij       = MixingMap(mytype_atom1,mytype_atom2)%n
605 >       mij       = MixingMap(mytype_atom1,mytype_atom2)%m
606 >       vcij      = MixingMap(mytype_atom1,mytype_atom2)%vpair_pot              
607  
608 <       if (rij.lt.rcj) then      
810 <          ! Calculate rho,drho and d2rho for atom1
811 <          call eam_splint(EAMList%EAMParams(mytype_atom2)%eam_nr, &
812 <               EAMList%EAMParams(mytype_atom2)%eam_rvals, &
813 <               EAMList%EAMParams(mytype_atom2)%eam_rho_r, &
814 <               EAMList%EAMParams(mytype_atom2)%eam_rho_r_pp, &
815 <               rij, rhb,drhb,d2rhb)
608 >       vptmp = epsilonij*((aij/r)**nij)
609  
817          !! Calculate Phi(r) for atom2.
818          call eam_splint(EAMList%EAMParams(mytype_atom2)%eam_nr, &
819               EAMList%EAMParams(mytype_atom2)%eam_rvals, &
820               EAMList%EAMParams(mytype_atom2)%eam_phi_r, &
821               EAMList%EAMParams(mytype_atom2)%eam_phi_r_pp, &
822               rij, phb,dphb,d2phb)
823       endif
610  
611 <       if (rij.lt.rci) then
612 <          phab = phab + 0.5E0_DP*(rhb/rha)*pha
827 <          dvpdr = dvpdr + 0.5E0_DP*((rhb/rha)*dpha + &
828 <               pha*((drhb/rha) - (rhb*drha/rha/rha)))
829 <          d2vpdrdr = d2vpdrdr + 0.5E0_DP*((rhb/rha)*d2pha + &
830 <               2.0E0_DP*dpha*((drhb/rha) - (rhb*drha/rha/rha)) + &
831 <               pha*((d2rhb/rha) - 2.0E0_DP*(drhb*drha/rha/rha) + &
832 <               (2.0E0_DP*rhb*drha*drha/rha/rha/rha) - (rhb*d2rha/rha/rha)))
833 <       endif
611 >       dvpdr = -nij*vptmp/r
612 >       drhodr = -mij*((aij/r)**mij)/r
613  
614 <       if (rij.lt.rcj) then
615 <          phab = phab + 0.5E0_DP*(rha/rhb)*phb
616 <          dvpdr = dvpdr + 0.5E0_DP*((rha/rhb)*dphb + &
617 <               phb*((drha/rhb) - (rha*drhb/rhb/rhb)))
618 <          d2vpdrdr = d2vpdrdr + 0.5E0_DP*((rha/rhb)*d2phb + &
619 <               2.0E0_DP*dphb*((drha/rhb) - (rha*drhb/rhb/rhb)) + &
841 <               phb*((d2rha/rhb) - 2.0E0_DP*(drha*drhb/rhb/rhb) + &
842 <               (2.0E0_DP*rha*drhb*drhb/rhb/rhb/rhb) - (rha*d2rhb/rhb/rhb)))
843 <       endif
614 >      
615 >       dudr = drhodr*(dfrhodrho(atom1)+dfrhodrho(atom2)) &
616 >            + dvpdr
617 >      
618 >       pot_temp = vptmp + vcij
619 >
620  
845       drhoidr = drha
846       drhojdr = drhb
847
848       d2rhoidrdr = d2rha
849       d2rhojdrdr = d2rhb
850
851
621   #ifdef IS_MPI
622 <       dudr = drhojdr*dfrhodrho_row(atom1)+drhoidr*dfrhodrho_col(atom2) &
622 >       dudr = drhodr*(dfrhodrho_row(atom1)+dfrhodrho_col(atom2)) &
623              + dvpdr
624  
625   #else
626 <       dudr = drhojdr*dfrhodrho(atom1)+drhoidr*dfrhodrho(atom2) &
626 >       dudr = drhodr*(dfrhodrho(atom1)+dfrhodrho(atom2)) &
627              + dvpdr
859       ! write(*,*) "Atom1,Atom2, dfrhodrho(atom1) dfrhodrho(atom2): ", atom1,atom2,dfrhodrho(atom1),dfrhodrho(atom2)
628   #endif
629  
630 +
631         fx = dudr * drdx
632         fy = dudr * drdy
633         fz = dudr * drdz
# Line 866 | Line 635 | contains
635  
636   #ifdef IS_MPI
637         if (do_pot) then
638 <          pot_Row(METALLIC_POT,atom1) = pot_Row(METALLIC_POT,atom1) + phab*0.5
639 <          pot_Col(METALLIC_POT,atom2) = pot_Col(METALLIC_POT,atom2) + phab*0.5
638 >          pot_Row(METALLIC_POT,atom1) = pot_Row(METALLIC_POT,atom1) + (pot_temp)*0.5
639 >          pot_Col(METALLIC_POT,atom2) = pot_Col(METALLIC_POT,atom2) + (pot_temp)*0.5
640         end if
641  
642         f_Row(1,atom1) = f_Row(1,atom1) + fx
# Line 880 | Line 649 | contains
649   #else
650  
651         if(do_pot) then
652 <          pot = pot + phab
652 >          pot = pot + pot_temp
653         end if
654  
655         f(1,atom1) = f(1,atom1) + fx
# Line 892 | Line 661 | contains
661         f(3,atom2) = f(3,atom2) - fz
662   #endif
663  
664 <       vpair = vpair + phab
664 >      
665   #ifdef IS_MPI
666         id1 = AtomRowToGlobal(atom1)
667         id2 = AtomColToGlobal(atom2)
# Line 909 | Line 678 | contains
678  
679         endif
680  
912       if (nmflag) then
681  
682 <          drhoidr = drha
915 <          drhojdr = drhb
916 <          d2rhoidrdr = d2rha
917 <          d2rhojdrdr = d2rhb
682 >  end subroutine do_sc_pair
683  
919 #ifdef IS_MPI
920          d2 = d2vpdrdr + &
921               d2rhoidrdr*dfrhodrho_col(atom2) + &
922               d2rhojdrdr*dfrhodrho_row(atom1) + &
923               drhoidr*drhoidr*d2frhodrhodrho_col(atom2) + &
924               drhojdr*drhojdr*d2frhodrhodrho_row(atom1)
684  
926 #else
685  
686 <          d2 = d2vpdrdr + &
929 <               d2rhoidrdr*dfrhodrho(atom2) + &
930 <               d2rhojdrdr*dfrhodrho(atom1) + &
931 <               drhoidr*drhoidr*d2frhodrhodrho(atom2) + &
932 <               drhojdr*drhojdr*d2frhodrhodrho(atom1)
933 < #endif
934 <       end if
935 <
936 <    endif
937 <  end subroutine do_eam_pair
938 <
939 <
940 <  subroutine eam_splint(nx, xa, ya, yppa, x, y, dy, d2y)
941 <
942 <    integer :: atype, nx, j
943 <    real( kind = DP ), dimension(:) :: xa
944 <    real( kind = DP ), dimension(:) :: ya
945 <    real( kind = DP ), dimension(:) :: yppa
946 <    real( kind = DP ) :: x, y
947 <    real( kind = DP ) :: dy, d2y
948 <    real( kind = DP ) :: del, h, a, b, c, d
949 <    integer :: pp_arraySize
950 <
951 <
952 <    ! this spline code assumes that the x points are equally spaced
953 <    ! do not attempt to use this code if they are not.
954 <
955 <
956 <    ! find the closest point with a value below our own:
957 <    j = FLOOR(real((nx-1),kind=dp) * (x - xa(1)) / (xa(nx) - xa(1))) + 1
958 <
959 <    ! check to make sure we're inside the spline range:
960 <    if ((j.gt.nx).or.(j.lt.1)) then
961 <       write(errMSG,*) "EAM_splint: x is outside bounds of spline: ",x,j
962 <       call handleError(routineName,errMSG)
963 <    endif
964 <    ! check to make sure we haven't screwed up the calculation of j:
965 <    if ((x.lt.xa(j)).or.(x.gt.xa(j+1))) then
966 <       if (j.ne.nx) then
967 <          write(errMSG,*) "EAM_splint:",x," x is outside bounding range"
968 <          call handleError(routineName,errMSG)
969 <       endif
970 <    endif
971 <
972 <    del = xa(j+1) - x
973 <    h = xa(j+1) - xa(j)
974 <
975 <    a = del / h
976 <    b = 1.0E0_DP - a
977 <    c = a*(a*a - 1.0E0_DP)*h*h/6.0E0_DP
978 <    d = b*(b*b - 1.0E0_DP)*h*h/6.0E0_DP
979 <
980 <    y = a*ya(j) + b*ya(j+1) + c*yppa(j) + d*yppa(j+1)
981 <
982 <    dy = (ya(j+1)-ya(j))/h &
983 <         - (3.0E0_DP*a*a - 1.0E0_DP)*h*yppa(j)/6.0E0_DP &
984 <         + (3.0E0_DP*b*b - 1.0E0_DP)*h*yppa(j+1)/6.0E0_DP
985 <
986 <
987 <    d2y = a*yppa(j) + b*yppa(j+1)
988 <
989 <
990 <  end subroutine eam_splint
991 <
992 <
993 <  subroutine eam_spline(nx, xa, ya, yppa, yp1, ypn, boundary)
994 <
995 <
996 <    ! yp1 and ypn are the first derivatives of y at the two endpoints
997 <    ! if boundary is 'L' the lower derivative is used
998 <    ! if boundary is 'U' the upper derivative is used
999 <    ! if boundary is 'B' then both derivatives are used
1000 <    ! if boundary is anything else, then both derivatives are assumed to be 0
1001 <
1002 <    integer :: nx, i, k, max_array_size
1003 <
1004 <    real( kind = DP ), dimension(:)        :: xa
1005 <    real( kind = DP ), dimension(:)        :: ya
1006 <    real( kind = DP ), dimension(:)        :: yppa
1007 <    real( kind = DP ), dimension(size(xa)) :: u
1008 <    real( kind = DP ) :: yp1,ypn,un,qn,sig,p
1009 <    character(len=*) :: boundary
1010 <
1011 <    ! make sure the sizes match
1012 <    if ((nx /= size(xa)) .or. (nx /= size(ya))) then
1013 <       call handleWarning("EAM_SPLINE","Array size mismatch")
1014 <    end if
1015 <
1016 <    if ((boundary.eq.'l').or.(boundary.eq.'L').or. &
1017 <         (boundary.eq.'b').or.(boundary.eq.'B')) then
1018 <       yppa(1) = -0.5E0_DP
1019 <       u(1) = (3.0E0_DP/(xa(2)-xa(1)))*((ya(2)-&
1020 <            ya(1))/(xa(2)-xa(1))-yp1)
1021 <    else
1022 <       yppa(1) = 0.0E0_DP
1023 <       u(1)  = 0.0E0_DP
1024 <    endif
1025 <
1026 <    do i = 2, nx - 1
1027 <       sig = (xa(i) - xa(i-1)) / (xa(i+1) - xa(i-1))
1028 <       p = sig * yppa(i-1) + 2.0E0_DP
1029 <       yppa(i) = (sig - 1.0E0_DP) / p
1030 <       u(i) = (6.0E0_DP*((ya(i+1)-ya(i))/(xa(i+1)-xa(i)) - &
1031 <            (ya(i)-ya(i-1))/(xa(i)-xa(i-1)))/ &
1032 <            (xa(i+1)-xa(i-1)) - sig * u(i-1))/p
1033 <    enddo
1034 <
1035 <    if ((boundary.eq.'u').or.(boundary.eq.'U').or. &
1036 <         (boundary.eq.'b').or.(boundary.eq.'B')) then
1037 <       qn = 0.5E0_DP
1038 <       un = (3.0E0_DP/(xa(nx)-xa(nx-1)))* &
1039 <            (ypn-(ya(nx)-ya(nx-1))/(xa(nx)-xa(nx-1)))
1040 <    else
1041 <       qn = 0.0E0_DP
1042 <       un = 0.0E0_DP
1043 <    endif
1044 <
1045 <    yppa(nx)=(un-qn*u(nx-1))/(qn*yppa(nx-1)+1.0E0_DP)
1046 <
1047 <    do k = nx-1, 1, -1
1048 <       yppa(k)=yppa(k)*yppa(k+1)+u(k)
1049 <    enddo
1050 <
1051 <  end subroutine eam_spline
1052 <
1053 < end module eam
686 > end module suttonchen

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines