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 2434 by chuckv, Tue Nov 15 16:18:36 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
142    public :: calc_SC_prepair_rho
143 +  public :: calc_SC_preforce_Frho
144    public :: clean_SC
145    public :: destroySCtypes
146    public :: getSCCut
147 + ! public :: setSCDefaultCutoff
148 + ! public :: setSCUniformCutoff
149 +  public :: useGeometricMixing
150  
151   contains
152  
153  
154 <  subroutine newSCtype(c,m,n,alpha,epsilon,c_ident,status)
155 <    real (kind = dp )                      :: lattice_constant
156 <    integer                                :: eam_nrho
157 <    real (kind = dp )                      :: eam_drho
158 <    integer                                :: eam_nr
159 <    real (kind = dp )                      :: eam_dr
160 <    real (kind = dp )                      :: rcut
161 <    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
154 >  subroutine newSCtype(c_ident,c,m,n,alpha,epsilon,status)
155 >    real (kind = dp )                      :: c ! Density Scaling
156 >    real (kind = dp )                      :: m ! Density Exponent
157 >    real (kind = dp )                      :: n ! Pair Potential Exponent
158 >    real (kind = dp )                      :: alpha ! Length Scaling
159 >    real (kind = dp )                      :: epsilon ! Energy Scaling
160 >
161 >
162      integer                                :: c_ident
163      integer                                :: status
164  
165 <    integer                                :: nAtypes,nEAMTypes,myATID
165 >    integer                                :: nAtypes,nSCTypes,myATID
166      integer                                :: maxVals
167      integer                                :: alloc_stat
168      integer                                :: current
# Line 168 | Line 172 | contains
172  
173  
174      !! 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.
175  
176  
177      ! check to see if this is the first time into
178 <    if (.not.associated(EAMList%EAMParams)) then
179 <       call getMatchingElementList(atypes, "is_EAM", .true., nEAMtypes, MatchList)
180 <       EAMList%n_eam_types = nEAMtypes
181 <       allocate(EAMList%EAMParams(nEAMTypes))
178 >    if (.not.associated(SCList%SCTypes)) then
179 >       call getMatchingElementList(atypes, "is_SuttonChen", .true., nSCtypes, MatchList)
180 >       SCList%nSCtypes = nSCtypes
181 >       allocate(SCList%SCTypes(nSCTypes))
182         nAtypes = getSize(atypes)
183 <       allocate(EAMList%atidToEAMType(nAtypes))
183 >       allocate(SCList%atidToSCType(nAtypes))
184      end if
185  
186 <    EAMList%currentAddition = EAMList%currentAddition + 1
187 <    current = EAMList%currentAddition
186 >    SCList%currentSCType = SCList%currentSCType + 1
187 >    current = SCList%currentSCType
188  
189      myATID =  getFirstMatchingElement(atypes, "c_ident", c_ident)
190 <    EAMList%atidToEAMType(myATID) = current
190 >    SCList%atidToSCType(myATID) = current
191  
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
192  
193    
194 <    EAMList%EAMParams(current)%eam_atype    = c_ident
195 <    EAMList%EAMParams(current)%eam_lattice  = lattice_constant
196 <    EAMList%EAMParams(current)%eam_nrho     = eam_nrho
197 <    EAMList%EAMParams(current)%eam_drho     = eam_drho
198 <    EAMList%EAMParams(current)%eam_nr       = eam_nr
199 <    EAMList%EAMParams(current)%eam_dr       = eam_dr
200 <    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
194 >    SCList%SCTypes(current)%atid         = c_ident
195 >    SCList%SCTypes(current)%alpha        = alpha
196 >    SCList%SCTypes(current)%c            = c
197 >    SCList%SCTypes(current)%m            = m
198 >    SCList%SCTypes(current)%n            = n
199 >    SCList%SCTypes(current)%epsilon      = epsilon
200 >  end subroutine newSCtype
201  
202 <  end subroutine newEAMtype
202 >  
203 >  subroutine destroySCTypes()
204 >    if (associated(SCList%SCtypes)) then
205 >       deallocate(SCList%SCTypes)
206 >       SCList%SCTypes=>null()
207 >    end if
208 >    if (associated(SCList%atidToSCtype)) then
209 >       deallocate(SCList%atidToSCtype)
210 >       SCList%atidToSCtype=>null()
211 >    end if
212  
213  
214 <  ! kills all eam types entered and sets simulation to uninitalized
211 <  subroutine destroyEAMtypes()
212 <    integer :: i
213 <    type(EAMType), pointer :: tempEAMType=>null()
214 >  end subroutine destroySCTypes
215  
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()
216  
222    eamList%n_eam_types = 0
223    eamList%currentAddition = 0
217  
218 <  end subroutine destroyEAMtypes
226 <
227 <  function getEAMCut(atomID) result(cutValue)
218 >  function getSCCut(atomID) result(cutValue)
219      integer, intent(in) :: atomID
220 <    integer :: eamID
220 >    integer :: scID
221      real(kind=dp) :: cutValue
222      
223 <    eamID = EAMList%atidToEAMType(atomID)
224 <    cutValue = EAMList%EAMParams(eamID)%eam_rcut
225 <  end function getEAMCut
223 >    scID = SCList%atidToSCType(atomID)
224 >    cutValue = SCList%SCTypes(scID)%sc_rcut
225 >  end function getSCCut
226  
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
227  
228  
229 <    status = 0
230 <    if (EAMList%currentAddition == 0) then
231 <       call handleError("init_EAM_FF","No members in EAMList")
232 <       status = -1
229 >
230 >  subroutine createMixingMap()
231 >    integer :: nSCtypes, i, j
232 >    real ( kind = dp ) :: e1, e2,m1,m2,alpha1,alpha2,n1,n2
233 >    real ( kind = dp ) :: rcut6, tp6, tp12
234 >    logical :: isSoftCore1, isSoftCore2, doShift
235 >
236 >    if (SCList%currentSCtype == 0) then
237 >       call handleError("SuttonChen", "No members in SCMap")
238         return
239      end if
240  
241 +    nSCtypes = SCList%nSCtypes
242  
243 <    do i = 1, EAMList%currentAddition
243 >    if (.not. allocated(MixingMap)) then
244 >       allocate(MixingMap(nSCtypes, nSCtypes))
245 >    endif
246  
247 <       ! Build array of r values
247 >    do i = 1, nSCtypes
248  
249 <       do j = 1,EAMList%EAMParams(i)%eam_nr
250 <          EAMList%EAMParams(i)%eam_rvals(j) = &
251 <               real(j-1,kind=dp)* &
252 <               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
249 >       e1 = SCList%SCtypes(i)%epsilon
250 >       m1 = SCList%SCtypes(i)%m
251 >       n1 = SCList%SCtypes(i)%n
252 >       alpha1 = SCList%SCtypes(i)%alpha
253  
254 <       ! precompute the pair potential and get it into kcal / mol:
255 <       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
254 >       do j = i, nSCtypes
255 >          
256  
257 +          e2 = SCList%SCtypes(j)%epsilon
258 +          m2 = SCList%SCtypes(j)%m
259 +          n2 = SCList%SCtypes(j)%n
260 +          alpha2 = SCList%SCtypes(j)%alpha
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')
262 >          if (useGeometricDistanceMixing) then
263 >             MixingMap(i,j)%alpha = sqrt(alpha1 * alpha2) !SC formulation
264 >          else
265 >             MixingMap(i,j)%alpha = 0.5_dp * (alpha1 + alpha2) ! Goddard formulation
266 >          endif
267 >
268 >          MixingMap(i,j)%epsilon = sqrt(e1 * e2)
269 >          MixingMap(i,j)%m = 0.5_dp*(m1+m2)
270 >          MixingMap(i,j)%n = 0.5_dp*(n1+n2)
271 >          MixingMap(i,j)%alpha = 0.5_dp*(alpha1+alpha2)
272 >          MixingMap(i,j)%rcut = 2.0_dp *MixingMap(i,j)%alpha
273 >          MixingMap(i,j)%vpair_pot = MixingMap(i,j)%epsilon* &
274 >               (MixingMap(i,j)%alpha/MixingMap(i,j)%rcut)**MixingMap(i,j)%n
275 >          if (i.ne.j) then
276 >             MixingMap(j,i)%epsilon    = MixingMap(i,j)%epsilon
277 >             MixingMap(j,i)%m          = MixingMap(i,j)%m
278 >             MixingMap(j,i)%n          = MixingMap(i,j)%n
279 >             MixingMap(j,i)%alpha      = MixingMap(i,j)%alpha
280 >             MixingMap(j,i)%rcut = MixingMap(i,j)%rcut
281 >             MixingMap(j,i)%vpair_pot = MixingMap(i,j)%vpair_pot
282 >          endif
283 >       enddo
284      enddo
285 +    
286 +    haveMixingMap = .true.
287 +    
288 +  end subroutine createMixingMap
289 +  
290  
301    !       current_rcut_max = EAMList%EAMParams(1)%eam_rcut
302    !! find the smallest rcut for any eam atype
303    !       do i = 2, EAMList%currentAddition
304    !          current_rcut_max =max(current_rcut_max,EAMList%EAMParams(i)%eam_rcut)
305    !       end do
306
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
291    !! routine checks to see if array is allocated, deallocates array if allocated
292    !! and then creates the array to the required size
293 <  subroutine allocateEAM(status)
293 >  subroutine allocateSC(status)
294      integer, intent(out) :: status
295  
296   #ifdef IS_MPI
# Line 338 | Line 306 | contains
306      nAtomsInCol = getNatomsInCol(plan_atom_col)
307   #endif
308  
309 +
310 +
311      if (allocated(frho)) deallocate(frho)
312      allocate(frho(nlocal),stat=alloc_stat)
313 <    if (alloc_stat /= 0) then
313 >    if (alloc_stat /= 0) then
314         status = -1
315         return
316      end if
317 +
318      if (allocated(rho)) deallocate(rho)
319      allocate(rho(nlocal),stat=alloc_stat)
320      if (alloc_stat /= 0) then
# Line 358 | Line 329 | contains
329         return
330      end if
331  
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
332   #ifdef IS_MPI
333  
334      if (allocated(rho_tmp)) deallocate(rho_tmp)
# Line 393 | Line 357 | contains
357         status = -1
358         return
359      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
360  
361  
362      ! Now do column arrays
# Line 421 | Line 379 | contains
379         status = -1
380         return
381      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
382  
383   #endif
384  
385 <  end subroutine allocateEAM
385 >  end subroutine allocateSC
386  
387    !! C sets rcut to be the largest cutoff of any atype
388    !! present in this simulation. Doesn't include all atypes
389    !! sim knows about, just those in the simulation.
390 <  subroutine setCutoffEAM(rcut, status)
390 >  subroutine setCutoffSC(rcut, status)
391      real(kind=dp) :: rcut
392      integer :: status
393      status = 0
394  
395 <    EAM_rcut = rcut
395 >    SC_rcut = rcut
396  
397 <  end subroutine setCutoffEAM
397 >  end subroutine setCutoffSC
398  
399 +  subroutine useGeometricMixing()
400 +    useGeometricDistanceMixing = .true.
401 +    haveMixingMap = .false.
402 +    return
403 +  end subroutine useGeometricMixing
404 +  
405  
406  
449  subroutine clean_EAM()
407  
408 +
409 +
410 +
411 +
412 +
413 +  subroutine clean_SC()
414 +
415      ! clean non-IS_MPI first
416      frho = 0.0_dp
417      rho  = 0.0_dp
# Line 462 | Line 426 | contains
426      dfrhodrho_row = 0.0_dp
427      dfrhodrho_col = 0.0_dp
428   #endif
429 <  end subroutine clean_EAM
429 >  end subroutine clean_SC
430  
431  
432  
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
433    !! Calculates rho_r
434 <  subroutine calc_eam_prepair_rho(atom1,atom2,d,r,rijsq)
434 >  subroutine calc_sc_prepair_rho(atom1,atom2,d,r,rijsq)
435      integer :: atom1,atom2
436      real(kind = dp), dimension(3) :: d
437      real(kind = dp), intent(inout)               :: r
# Line 561 | Line 442 | contains
442      real(kind = dp) :: rho_j_at_i
443  
444      ! we don't use the derivatives, dummy variables
445 <    real( kind = dp) :: drho,d2rho
446 <    integer :: eam_err
445 >    real( kind = dp) :: drho
446 >    integer :: sc_err
447      
448      integer :: atid1,atid2 ! Global atid    
449      integer :: myid_atom1 ! EAM atid
# Line 582 | Line 463 | contains
463      Atid2 = Atid(Atom2)
464   #endif
465  
466 <    Myid_atom1 = Eamlist%atidtoeamtype(Atid1)
467 <    Myid_atom2 = Eamlist%atidtoeamtype(Atid2)
466 >    Myid_atom1 = SCList%atidtoSCtype(Atid1)
467 >    Myid_atom2 = SCList%atidtoSCtype(Atid2)
468  
588    if (r.lt.EAMList%EAMParams(myid_atom1)%eam_rcut) then
589
590
591
592       call eam_splint(EAMList%EAMParams(myid_atom1)%eam_nr, &
593            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)
469  
470  
471 +       rho_i_at_j = (MixingMap(Myid_atom1,Myid_atom2)%alpha/r)&
472 +            **MixingMap(Myid_atom1,Myid_atom2)%m
473 +       rho_j_at_i = rho_i_at_j
474  
475   #ifdef  IS_MPI
476         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
477         rho_row(atom1) = rho_row(atom1) + rho_j_at_i
478   #else
479 +       rho(atom2) = rho(atom2) + rho_i_at_j
480         rho(atom1) = rho(atom1) + rho_j_at_i
481   #endif
623    endif
482  
483 +  end subroutine calc_sc_prepair_rho
484  
485  
486 <
487 <
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)
486 > !! Calculate the rho_a for all local atoms
487 >  subroutine calc_sc_preforce_Frho(nlocal,pot)
488      integer :: nlocal
489      real(kind=dp) :: pot
490      integer :: i,j
491      integer :: atom
492      real(kind=dp) :: U,U1,U2
493      integer :: atype1
494 <    integer :: me,atid1
495 <    integer :: n_rho_points
494 >    integer :: atid1
495 >    integer :: myid
496  
497  
498      cleanme = .true.
499      !! Scatter the electron density from  pre-pair calculation back to local atoms
500   #ifdef IS_MPI
501 <    call scatter(rho_row,rho,plan_atom_row,eam_err)
502 <    if (eam_err /= 0 ) then
501 >    call scatter(rho_row,rho,plan_atom_row,sc_err)
502 >    if (sc_err /= 0 ) then
503         write(errMsg,*) " Error scattering rho_row into rho"
504         call handleError(RoutineName,errMesg)
505      endif
506 <    call scatter(rho_col,rho_tmp,plan_atom_col,eam_err)
507 <    if (eam_err /= 0 ) then
506 >    call scatter(rho_col,rho_tmp,plan_atom_col,sc_err)
507 >    if (sc_err /= 0 ) then
508         write(errMsg,*) " Error scattering rho_col into rho"
509         call handleError(RoutineName,errMesg)
510 +
511      endif
512  
513      rho(1:nlocal) = rho(1:nlocal) + rho_tmp(1:nlocal)
# Line 663 | Line 515 | contains
515  
516  
517  
518 <    !! Calculate F(rho) and derivative
518 >    !! Calculate F(rho) and derivative
519      do atom = 1, nlocal
520 <       atid1 = atid(atom)
521 <       me = eamList%atidToEAMtype(atid1)
522 <       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
520 >       Myid = SCList%atidtoSctype(Atid(atom))
521 >       frho(atom) = -SCList%SCTypes(Myid)%c * &
522 >            SCList%SCTypes(Myid)%epsilon * sqrt(rho(i))
523  
524 <
690 <       frho(atom) = u
691 <       dfrhodrho(atom) = u1
692 <       d2frhodrhodrho(atom) = u2
524 >       dfrhodrho(atom) = 0.5_dp*frho(atom)/rho(atom)
525         pot = pot + u
694
526      enddo
527  
697
698
528   #ifdef IS_MPI
529      !! communicate f(rho) and derivatives back into row and column arrays
530 <    call gather(frho,frho_row,plan_atom_row, eam_err)
531 <    if (eam_err /=  0) then
530 >    call gather(frho,frho_row,plan_atom_row, sc_err)
531 >    if (sc_err /=  0) then
532         call handleError("cal_eam_forces()","MPI gather frho_row failure")
533      endif
534 <    call gather(dfrhodrho,dfrhodrho_row,plan_atom_row, eam_err)
535 <    if (eam_err /=  0) then
534 >    call gather(dfrhodrho,dfrhodrho_row,plan_atom_row, sc_err)
535 >    if (sc_err /=  0) then
536         call handleError("cal_eam_forces()","MPI gather dfrhodrho_row failure")
537      endif
538 <    call gather(frho,frho_col,plan_atom_col, eam_err)
539 <    if (eam_err /=  0) then
538 >    call gather(frho,frho_col,plan_atom_col, sc_err)
539 >    if (sc_err /=  0) then
540         call handleError("cal_eam_forces()","MPI gather frho_col failure")
541      endif
542 <    call gather(dfrhodrho,dfrhodrho_col,plan_atom_col, eam_err)
543 <    if (eam_err /=  0) then
542 >    call gather(dfrhodrho,dfrhodrho_col,plan_atom_col, sc_err)
543 >    if (sc_err /=  0) then
544         call handleError("cal_eam_forces()","MPI gather dfrhodrho_col failure")
545      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
546   #endif
547 +    
548 +    
549 +  end subroutine calc_sc_preforce_Frho
550  
551  
552 <  end subroutine calc_eam_preforce_Frho
553 <
731 <
732 <
733 <
734 <  !! Does EAM pairwise Force calculation.  
735 <  subroutine do_eam_pair(atom1, atom2, d, rij, r2, sw, vpair, fpair, &
552 >  !! Does Sutton-Chen  pairwise Force calculation.  
553 >  subroutine do_sc_pair(atom1, atom2, d, rij, r2, sw, vpair, fpair, &
554         pot, f, do_pot)
555      !Arguments    
556      integer, intent(in) ::  atom1, atom2
# Line 745 | Line 563 | contains
563      logical, intent(in) :: do_pot
564  
565      real( kind = dp ) :: drdx,drdy,drdz
566 <    real( kind = dp ) :: d2
567 <    real( kind = dp ) :: phab,pha,dvpdr,d2vpdrdr
750 <    real( kind = dp ) :: rha,drha,d2rha, dpha
751 <    real( kind = dp ) :: rhb,drhb,d2rhb, dphb
566 >    real( kind = dp ) :: dvpdr
567 >    real( kind = dp ) :: drhodr
568      real( kind = dp ) :: dudr
569 <    real( kind = dp ) :: rci,rcj
569 >    real( kind = dp ) :: rcij
570      real( kind = dp ) :: drhoidr,drhojdr
755    real( kind = dp ) :: d2rhoidrdr
756    real( kind = dp ) :: d2rhojdrdr
571      real( kind = dp ) :: Fx,Fy,Fz
572      real( kind = dp ) :: r,d2pha,phb,d2phb
573 <
573 >    real( kind = dp ) :: pot_temp,vptmp
574 >    real( kind = dp ) :: epsilonij,aij,nij,mij,vcij
575      integer :: id1,id2
576      integer  :: mytype_atom1
577      integer  :: mytype_atom2
# Line 765 | Line 580 | contains
580  
581      ! write(*,*) "Frho: ", Frho(atom1)
582  
583 <    phab = 0.0E0_DP
583 >
584      dvpdr = 0.0E0_DP
770    d2vpdrdr = 0.0E0_DP
585  
772    if (rij .lt. EAM_rcut) then
586  
587   #ifdef IS_MPI
588         atid1 = atid_row(atom1)
# Line 779 | Line 592 | contains
592         atid2 = atid(atom2)
593   #endif
594  
595 <       mytype_atom1 = EAMList%atidToEAMType(atid1)
596 <       mytype_atom2 = EAMList%atidTOEAMType(atid2)
595 >       mytype_atom1 = SCList%atidToSCType(atid1)
596 >       mytype_atom2 = SCList%atidTOSCType(atid2)
597  
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
598         drdx = d(1)/rij
599         drdy = d(2)/rij
600         drdz = d(3)/rij
601  
602 <       if (rij.lt.rci) then
603 <          call eam_splint(EAMList%EAMParams(mytype_atom1)%eam_nr, &
604 <               EAMList%EAMParams(mytype_atom1)%eam_rvals, &
605 <               EAMList%EAMParams(mytype_atom1)%eam_rho_r, &
606 <               EAMList%EAMParams(mytype_atom1)%eam_rho_r_pp, &
607 <               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
602 >                
603 >       epsilonij = MixingMap(mytype_atom1,mytype_atom2)%epsilon
604 >       aij       = MixingMap(mytype_atom1,mytype_atom2)%alpha
605 >       nij       = MixingMap(mytype_atom1,mytype_atom2)%n
606 >       mij       = MixingMap(mytype_atom1,mytype_atom2)%m
607 >       vcij      = MixingMap(mytype_atom1,mytype_atom2)%vpair_pot              
608  
609 <       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)
609 >       vptmp = epsilonij*((aij/r)**nij)
610  
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
611  
612 <       if (rij.lt.rci) then
613 <          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
612 >       dvpdr = -nij*vptmp/r
613 >       drhodr = -mij*((aij/r)**mij)/r
614  
615 <       if (rij.lt.rcj) then
616 <          phab = phab + 0.5E0_DP*(rha/rhb)*phb
617 <          dvpdr = dvpdr + 0.5E0_DP*((rha/rhb)*dphb + &
618 <               phb*((drha/rhb) - (rha*drhb/rhb/rhb)))
619 <          d2vpdrdr = d2vpdrdr + 0.5E0_DP*((rha/rhb)*d2phb + &
620 <               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
615 >      
616 >       dudr = drhodr*(dfrhodrho(atom1)+dfrhodrho(atom2)) &
617 >            + dvpdr
618 >      
619 >       pot_temp = vptmp + vcij
620 >
621  
845       drhoidr = drha
846       drhojdr = drhb
847
848       d2rhoidrdr = d2rha
849       d2rhojdrdr = d2rhb
850
851
622   #ifdef IS_MPI
623 <       dudr = drhojdr*dfrhodrho_row(atom1)+drhoidr*dfrhodrho_col(atom2) &
623 >       dudr = drhodr*(dfrhodrho_row(atom1)+dfrhodrho_col(atom2)) &
624              + dvpdr
625  
626   #else
627 <       dudr = drhojdr*dfrhodrho(atom1)+drhoidr*dfrhodrho(atom2) &
627 >       dudr = drhodr*(dfrhodrho(atom1)+dfrhodrho(atom2)) &
628              + dvpdr
859       ! write(*,*) "Atom1,Atom2, dfrhodrho(atom1) dfrhodrho(atom2): ", atom1,atom2,dfrhodrho(atom1),dfrhodrho(atom2)
629   #endif
630  
631 +
632         fx = dudr * drdx
633         fy = dudr * drdy
634         fz = dudr * drdz
# Line 866 | Line 636 | contains
636  
637   #ifdef IS_MPI
638         if (do_pot) then
639 <          pot_Row(METALLIC_POT,atom1) = pot_Row(METALLIC_POT,atom1) + phab*0.5
640 <          pot_Col(METALLIC_POT,atom2) = pot_Col(METALLIC_POT,atom2) + phab*0.5
639 >          pot_Row(METALLIC_POT,atom1) = pot_Row(METALLIC_POT,atom1) + (pot_temp)*0.5
640 >          pot_Col(METALLIC_POT,atom2) = pot_Col(METALLIC_POT,atom2) + (pot_temp)*0.5
641         end if
642  
643         f_Row(1,atom1) = f_Row(1,atom1) + fx
# Line 880 | Line 650 | contains
650   #else
651  
652         if(do_pot) then
653 <          pot = pot + phab
653 >          pot = pot + pot_temp
654         end if
655  
656         f(1,atom1) = f(1,atom1) + fx
# Line 892 | Line 662 | contains
662         f(3,atom2) = f(3,atom2) - fz
663   #endif
664  
665 <       vpair = vpair + phab
665 >      
666   #ifdef IS_MPI
667         id1 = AtomRowToGlobal(atom1)
668         id2 = AtomColToGlobal(atom2)
# Line 909 | Line 679 | contains
679  
680         endif
681  
912       if (nmflag) then
682  
683 <          drhoidr = drha
915 <          drhojdr = drhb
916 <          d2rhoidrdr = d2rha
917 <          d2rhojdrdr = d2rhb
683 >  end subroutine do_sc_pair
684  
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)
685  
926 #else
686  
687 <          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
687 > end module suttonchen

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines