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 2530 by chuckv, Fri Dec 30 00:18:28 2005 UTC

# Line 49 | Line 49 | module suttonchen
49    use status
50    use atype_module
51    use vector_class
52 +  use fForceOptions
53   #ifdef IS_MPI
54    use mpiSimulation
55   #endif
# Line 63 | Line 64 | module suttonchen
64    integer, save :: SC_Mixing_Policy
65    real(kind = dp), save :: SC_rcut
66    logical, save :: haveRcut = .false.
67 +  logical, save :: haveMixingMap = .false.
68 +  logical, save :: useGeometricDistanceMixing = .false.
69  
70 +
71 +
72 +
73    character(len = statusMsgSize) :: errMesg
74 <  integer :: eam_err
74 >  integer :: sc_err
75  
76    character(len = 200) :: errMsg
77    character(len=*), parameter :: RoutineName =  "Sutton-Chen MODULE"
# Line 81 | Line 87 | module suttonchen
87       real(kind=dp)     :: n
88       real(kind=dp)     :: alpha
89       real(kind=dp)     :: epsilon
90 +     real(kind=dp)     :: sc_rcut
91    end type SCtype
92  
93  
94    !! Arrays for derivatives used in force calculation
88  real( kind = dp), dimension(:), allocatable :: frho
95    real( kind = dp), dimension(:), allocatable :: rho
96 <
96 >  real( kind = dp), dimension(:), allocatable :: frho
97    real( kind = dp), dimension(:), allocatable :: dfrhodrho
92  real( kind = dp), dimension(:), allocatable :: d2frhodrhodrho
98  
99  
100 +
101    !! Arrays for MPI storage
102   #ifdef IS_MPI
103    real( kind = dp),save, dimension(:), allocatable :: dfrhodrho_col
# Line 101 | Line 107 | module suttonchen
107    real( kind = dp),save, dimension(:), allocatable :: rho_row
108    real( kind = dp),save, dimension(:), allocatable :: rho_col
109    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
110   #endif
111  
112    type, private :: SCTypeList
# Line 121 | Line 125 | module suttonchen
125   type :: MixParameters
126       real(kind=DP) :: alpha
127       real(kind=DP) :: epsilon
128 <     real(kind=dp) :: sigma6
128 >     real(kind=DP) :: m
129 >     real(Kind=DP) :: n
130 >     real(kind=DP) :: vpair_pot
131       real(kind=dp) :: rCut
126     real(kind=dp) :: delta
132       logical       :: rCutWasSet = .false.
133 <     logical       :: shiftedPot
129 <     logical       :: isSoftCore = .false.
133 >
134    end type MixParameters
135  
136    type(MixParameters), dimension(:,:), allocatable :: MixingMap
137  
138  
139  
136  public :: init_SC_FF
140    public :: setCutoffSC
141    public :: do_SC_pair
142    public :: newSCtype
143    public :: calc_SC_prepair_rho
144 +  public :: calc_SC_preforce_Frho
145    public :: clean_SC
146    public :: destroySCtypes
147    public :: getSCCut
148 + ! public :: setSCDefaultCutoff
149 + ! public :: setSCUniformCutoff
150 +
151  
152   contains
153  
154  
155 <  subroutine newSCtype(c,m,n,alpha,epsilon,c_ident,status)
156 <    real (kind = dp )                      :: lattice_constant
157 <    integer                                :: eam_nrho
158 <    real (kind = dp )                      :: eam_drho
159 <    integer                                :: eam_nr
160 <    real (kind = dp )                      :: eam_dr
161 <    real (kind = dp )                      :: rcut
162 <    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
155 >  subroutine newSCtype(c_ident,c,m,n,alpha,epsilon,status)
156 >    real (kind = dp )                      :: c ! Density Scaling
157 >    real (kind = dp )                      :: m ! Density Exponent
158 >    real (kind = dp )                      :: n ! Pair Potential Exponent
159 >    real (kind = dp )                      :: alpha ! Length Scaling
160 >    real (kind = dp )                      :: epsilon ! Energy Scaling
161 >
162 >
163      integer                                :: c_ident
164      integer                                :: status
165  
166 <    integer                                :: nAtypes,nEAMTypes,myATID
166 >    integer                                :: nAtypes,nSCTypes,myATID
167      integer                                :: maxVals
168      integer                                :: alloc_stat
169      integer                                :: current
# Line 168 | Line 173 | contains
173  
174  
175      !! 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.
176  
177  
178      ! check to see if this is the first time into
179 <    if (.not.associated(EAMList%EAMParams)) then
180 <       call getMatchingElementList(atypes, "is_EAM", .true., nEAMtypes, MatchList)
181 <       EAMList%n_eam_types = nEAMtypes
182 <       allocate(EAMList%EAMParams(nEAMTypes))
179 >    if (.not.associated(SCList%SCTypes)) then
180 >       call getMatchingElementList(atypes, "is_SC", .true., nSCtypes, MatchList)
181 >       SCList%nSCtypes = nSCtypes
182 >       allocate(SCList%SCTypes(nSCTypes))
183         nAtypes = getSize(atypes)
184 <       allocate(EAMList%atidToEAMType(nAtypes))
184 >       allocate(SCList%atidToSCType(nAtypes))
185      end if
186  
187 <    EAMList%currentAddition = EAMList%currentAddition + 1
188 <    current = EAMList%currentAddition
187 >    SCList%currentSCType = SCList%currentSCType + 1
188 >    current = SCList%currentSCType
189  
190      myATID =  getFirstMatchingElement(atypes, "c_ident", c_ident)
191 <    EAMList%atidToEAMType(myATID) = current
191 >    SCList%atidToSCType(myATID) = current
192  
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
193  
194    
195 <    EAMList%EAMParams(current)%eam_atype    = c_ident
196 <    EAMList%EAMParams(current)%eam_lattice  = lattice_constant
197 <    EAMList%EAMParams(current)%eam_nrho     = eam_nrho
198 <    EAMList%EAMParams(current)%eam_drho     = eam_drho
199 <    EAMList%EAMParams(current)%eam_nr       = eam_nr
200 <    EAMList%EAMParams(current)%eam_dr       = eam_dr
201 <    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
195 >    SCList%SCTypes(current)%atid         = c_ident
196 >    SCList%SCTypes(current)%alpha        = alpha
197 >    SCList%SCTypes(current)%c            = c
198 >    SCList%SCTypes(current)%m            = m
199 >    SCList%SCTypes(current)%n            = n
200 >    SCList%SCTypes(current)%epsilon      = epsilon
201 >  end subroutine newSCtype
202  
203 <  end subroutine newEAMtype
203 >  
204 >  subroutine destroySCTypes()
205 >    if (associated(SCList%SCtypes)) then
206 >       deallocate(SCList%SCTypes)
207 >       SCList%SCTypes=>null()
208 >    end if
209 >    if (associated(SCList%atidToSCtype)) then
210 >       deallocate(SCList%atidToSCtype)
211 >       SCList%atidToSCtype=>null()
212 >    end if
213  
214  
215 <  ! kills all eam types entered and sets simulation to uninitalized
211 <  subroutine destroyEAMtypes()
212 <    integer :: i
213 <    type(EAMType), pointer :: tempEAMType=>null()
215 >  end subroutine destroySCTypes
216  
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()
217  
218 <    eamList%n_eam_types = 0
219 <    eamList%currentAddition = 0
224 <
225 <  end subroutine destroyEAMtypes
226 <
227 <  function getEAMCut(atomID) result(cutValue)
218 >
219 >  function getSCCut(atomID) result(cutValue)
220      integer, intent(in) :: atomID
221 <    integer :: eamID
221 >    integer :: scID
222      real(kind=dp) :: cutValue
223      
224 <    eamID = EAMList%atidToEAMType(atomID)
225 <    cutValue = EAMList%EAMParams(eamID)%eam_rcut
226 <  end function getEAMCut
224 >    scID = SCList%atidToSCType(atomID)
225 >    cutValue = 2.0_dp * SCList%SCTypes(scID)%alpha
226 >  end function getSCCut
227  
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
228  
229  
230 <    status = 0
231 <    if (EAMList%currentAddition == 0) then
232 <       call handleError("init_EAM_FF","No members in EAMList")
233 <       status = -1
230 >
231 >  subroutine createMixingMap()
232 >    integer :: nSCtypes, i, j
233 >    real ( kind = dp ) :: e1, e2,m1,m2,alpha1,alpha2,n1,n2
234 >    real ( kind = dp ) :: rcut6, tp6, tp12
235 >    logical :: isSoftCore1, isSoftCore2, doShift
236 >
237 >    if (SCList%currentSCtype == 0) then
238 >       call handleError("SuttonChen", "No members in SCMap")
239         return
240      end if
241  
242 +    nSCtypes = SCList%nSCtypes
243  
244 <    do i = 1, EAMList%currentAddition
244 >    if (.not. allocated(MixingMap)) then
245 >       allocate(MixingMap(nSCtypes, nSCtypes))
246 >    endif
247 >    useGeometricDistanceMixing = usesGeometricDistanceMixing()
248 >    do i = 1, nSCtypes
249  
250 <       ! Build array of r values
250 >       e1 = SCList%SCtypes(i)%epsilon
251 >       m1 = SCList%SCtypes(i)%m
252 >       n1 = SCList%SCtypes(i)%n
253 >       alpha1 = SCList%SCtypes(i)%alpha
254  
255 <       do j = 1,EAMList%EAMParams(i)%eam_nr
256 <          EAMList%EAMParams(i)%eam_rvals(j) = &
258 <               real(j-1,kind=dp)* &
259 <               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
255 >       do j = i, nSCtypes
256 >          
257  
258 <       ! precompute the pair potential and get it into kcal / mol:
259 <       EAMList%EAMParams(i)%eam_phi_r(1) = 0.0E0_DP
260 <       do j = 2, EAMList%EAMParams(i)%eam_nr
261 <          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
258 >          e2 = SCList%SCtypes(j)%epsilon
259 >          m2 = SCList%SCtypes(j)%m
260 >          n2 = SCList%SCtypes(j)%n
261 >          alpha2 = SCList%SCtypes(j)%alpha
262  
263 +          if (useGeometricDistanceMixing) then
264 +             MixingMap(i,j)%alpha = sqrt(alpha1 * alpha2) !SC formulation
265 +          else
266 +             MixingMap(i,j)%alpha = 0.5_dp * (alpha1 + alpha2) ! Goddard formulation
267 +          endif
268  
269 <    do i = 1,  EAMList%currentAddition
270 <       number_r   = EAMList%EAMParams(i)%eam_nr
271 <       number_rho = EAMList%EAMParams(i)%eam_nrho
272 <
273 <       call eam_spline(number_r, EAMList%EAMParams(i)%eam_rvals, &
274 <            EAMList%EAMParams(i)%eam_rho_r, &
275 <            EAMList%EAMParams(i)%eam_rho_r_pp, &
276 <            0.0E0_DP, 0.0E0_DP, 'N')
277 <       call eam_spline(number_r, EAMList%EAMParams(i)%eam_rvals, &
278 <            EAMList%EAMParams(i)%eam_Z_r, &
279 <            EAMList%EAMParams(i)%eam_Z_r_pp, &
280 <            0.0E0_DP, 0.0E0_DP, 'N')
281 <       call eam_spline(number_rho, EAMList%EAMParams(i)%eam_rhovals, &
282 <            EAMList%EAMParams(i)%eam_F_rho, &
283 <            EAMList%EAMParams(i)%eam_F_rho_pp, &
284 <            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')
269 >          MixingMap(i,j)%epsilon = sqrt(e1 * e2)
270 >          MixingMap(i,j)%m = 0.5_dp*(m1+m2)
271 >          MixingMap(i,j)%n = 0.5_dp*(n1+n2)
272 >          MixingMap(i,j)%alpha = 0.5_dp*(alpha1+alpha2)
273 >          MixingMap(i,j)%rcut = 2.0_dp *MixingMap(i,j)%alpha
274 >          MixingMap(i,j)%vpair_pot = MixingMap(i,j)%epsilon* &
275 >               (MixingMap(i,j)%alpha/MixingMap(i,j)%rcut)**MixingMap(i,j)%n
276 >          if (i.ne.j) then
277 >             MixingMap(j,i)%epsilon    = MixingMap(i,j)%epsilon
278 >             MixingMap(j,i)%m          = MixingMap(i,j)%m
279 >             MixingMap(j,i)%n          = MixingMap(i,j)%n
280 >             MixingMap(j,i)%alpha      = MixingMap(i,j)%alpha
281 >             MixingMap(j,i)%rcut = MixingMap(i,j)%rcut
282 >             MixingMap(j,i)%vpair_pot = MixingMap(i,j)%vpair_pot
283 >          endif
284 >       enddo
285      enddo
286 +    
287 +    haveMixingMap = .true.
288 +    
289 +  end subroutine createMixingMap
290 +  
291  
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
292    !! routine checks to see if array is allocated, deallocates array if allocated
293    !! and then creates the array to the required size
294 <  subroutine allocateEAM(status)
294 >  subroutine allocateSC(status)
295      integer, intent(out) :: status
296  
297   #ifdef IS_MPI
# Line 338 | Line 307 | contains
307      nAtomsInCol = getNatomsInCol(plan_atom_col)
308   #endif
309  
310 +
311 +
312      if (allocated(frho)) deallocate(frho)
313      allocate(frho(nlocal),stat=alloc_stat)
314 <    if (alloc_stat /= 0) then
314 >    if (alloc_stat /= 0) then
315         status = -1
316         return
317      end if
318 +
319      if (allocated(rho)) deallocate(rho)
320      allocate(rho(nlocal),stat=alloc_stat)
321      if (alloc_stat /= 0) then
# Line 358 | Line 330 | contains
330         return
331      end if
332  
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
333   #ifdef IS_MPI
334  
335      if (allocated(rho_tmp)) deallocate(rho_tmp)
# Line 393 | Line 358 | contains
358         status = -1
359         return
360      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
361  
362  
363      ! Now do column arrays
# Line 421 | Line 380 | contains
380         status = -1
381         return
382      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
383  
384   #endif
385  
386 <  end subroutine allocateEAM
386 >  end subroutine allocateSC
387  
388    !! C sets rcut to be the largest cutoff of any atype
389    !! present in this simulation. Doesn't include all atypes
390    !! sim knows about, just those in the simulation.
391 <  subroutine setCutoffEAM(rcut, status)
391 >  subroutine setCutoffSC(rcut, status)
392      real(kind=dp) :: rcut
393      integer :: status
394      status = 0
395  
396 <    EAM_rcut = rcut
396 >    SC_rcut = rcut
397  
398 <  end subroutine setCutoffEAM
398 >  end subroutine setCutoffSC
399  
400 +  subroutine clean_SC()
401  
448
449  subroutine clean_EAM()
450
402      ! clean non-IS_MPI first
403      frho = 0.0_dp
404      rho  = 0.0_dp
# Line 462 | Line 413 | contains
413      dfrhodrho_row = 0.0_dp
414      dfrhodrho_col = 0.0_dp
415   #endif
416 <  end subroutine clean_EAM
416 >  end subroutine clean_SC
417  
418  
419  
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
420    !! Calculates rho_r
421 <  subroutine calc_eam_prepair_rho(atom1,atom2,d,r,rijsq)
421 >  subroutine calc_sc_prepair_rho(atom1,atom2,d,r,rijsq, rcut)
422      integer :: atom1,atom2
423      real(kind = dp), dimension(3) :: d
424      real(kind = dp), intent(inout)               :: r
425 <    real(kind = dp), intent(inout)               :: rijsq
425 >    real(kind = dp), intent(inout)               :: rijsq, rcut
426      ! value of electron density rho do to atom i at atom j
427      real(kind = dp) :: rho_i_at_j
428      ! value of electron density rho do to atom j at atom i
429      real(kind = dp) :: rho_j_at_i
430  
431      ! we don't use the derivatives, dummy variables
432 <    real( kind = dp) :: drho,d2rho
433 <    integer :: eam_err
432 >    real( kind = dp) :: drho
433 >    integer :: sc_err
434      
435      integer :: atid1,atid2 ! Global atid    
436      integer :: myid_atom1 ! EAM atid
# Line 582 | Line 450 | contains
450      Atid2 = Atid(Atom2)
451   #endif
452  
453 <    Myid_atom1 = Eamlist%atidtoeamtype(Atid1)
454 <    Myid_atom2 = Eamlist%atidtoeamtype(Atid2)
453 >    Myid_atom1 = SCList%atidtoSCtype(Atid1)
454 >    Myid_atom2 = SCList%atidtoSCtype(Atid2)
455  
588    if (r.lt.EAMList%EAMParams(myid_atom1)%eam_rcut) then
456  
457  
458 <
459 <       call eam_splint(EAMList%EAMParams(myid_atom1)%eam_nr, &
460 <            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 <
598 <
458 >       rho_i_at_j = (MixingMap(Myid_atom1,Myid_atom2)%alpha/r)&
459 >            **MixingMap(Myid_atom1,Myid_atom2)%m
460 >       rho_j_at_i = rho_i_at_j
461  
462   #ifdef  IS_MPI
463         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
464         rho_row(atom1) = rho_row(atom1) + rho_j_at_i
465   #else
466 +       rho(atom2) = rho(atom2) + rho_i_at_j
467         rho(atom1) = rho(atom1) + rho_j_at_i
468   #endif
623    endif
469  
470 +  end subroutine calc_sc_prepair_rho
471  
472  
473 <
474 <
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)
473 > !! Calculate the rho_a for all local atoms
474 >  subroutine calc_sc_preforce_Frho(nlocal,pot)
475      integer :: nlocal
476      real(kind=dp) :: pot
477      integer :: i,j
478      integer :: atom
479      real(kind=dp) :: U,U1,U2
480      integer :: atype1
481 <    integer :: me,atid1
482 <    integer :: n_rho_points
481 >    integer :: atid1
482 >    integer :: myid
483  
484  
485      cleanme = .true.
486      !! Scatter the electron density from  pre-pair calculation back to local atoms
487   #ifdef IS_MPI
488 <    call scatter(rho_row,rho,plan_atom_row,eam_err)
489 <    if (eam_err /= 0 ) then
488 >    call scatter(rho_row,rho,plan_atom_row,sc_err)
489 >    if (sc_err /= 0 ) then
490         write(errMsg,*) " Error scattering rho_row into rho"
491         call handleError(RoutineName,errMesg)
492      endif
493 <    call scatter(rho_col,rho_tmp,plan_atom_col,eam_err)
494 <    if (eam_err /= 0 ) then
493 >    call scatter(rho_col,rho_tmp,plan_atom_col,sc_err)
494 >    if (sc_err /= 0 ) then
495         write(errMsg,*) " Error scattering rho_col into rho"
496         call handleError(RoutineName,errMesg)
497 +
498      endif
499  
500      rho(1:nlocal) = rho(1:nlocal) + rho_tmp(1:nlocal)
# Line 663 | Line 502 | contains
502  
503  
504  
505 <    !! Calculate F(rho) and derivative
505 >    !! Calculate F(rho) and derivative
506      do atom = 1, nlocal
507 <       atid1 = atid(atom)
508 <       me = eamList%atidToEAMtype(atid1)
509 <       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
507 >       Myid = SCList%atidtoSctype(Atid(atom))
508 >       frho(atom) = -SCList%SCTypes(Myid)%c * &
509 >            SCList%SCTypes(Myid)%epsilon * sqrt(rho(i))
510  
511 <
690 <       frho(atom) = u
691 <       dfrhodrho(atom) = u1
692 <       d2frhodrhodrho(atom) = u2
511 >       dfrhodrho(atom) = 0.5_dp*frho(atom)/rho(atom)
512         pot = pot + u
694
513      enddo
514  
697
698
515   #ifdef IS_MPI
516      !! communicate f(rho) and derivatives back into row and column arrays
517 <    call gather(frho,frho_row,plan_atom_row, eam_err)
518 <    if (eam_err /=  0) then
517 >    call gather(frho,frho_row,plan_atom_row, sc_err)
518 >    if (sc_err /=  0) then
519         call handleError("cal_eam_forces()","MPI gather frho_row failure")
520      endif
521 <    call gather(dfrhodrho,dfrhodrho_row,plan_atom_row, eam_err)
522 <    if (eam_err /=  0) then
521 >    call gather(dfrhodrho,dfrhodrho_row,plan_atom_row, sc_err)
522 >    if (sc_err /=  0) then
523         call handleError("cal_eam_forces()","MPI gather dfrhodrho_row failure")
524      endif
525 <    call gather(frho,frho_col,plan_atom_col, eam_err)
526 <    if (eam_err /=  0) then
525 >    call gather(frho,frho_col,plan_atom_col, sc_err)
526 >    if (sc_err /=  0) then
527         call handleError("cal_eam_forces()","MPI gather frho_col failure")
528      endif
529 <    call gather(dfrhodrho,dfrhodrho_col,plan_atom_col, eam_err)
530 <    if (eam_err /=  0) then
529 >    call gather(dfrhodrho,dfrhodrho_col,plan_atom_col, sc_err)
530 >    if (sc_err /=  0) then
531         call handleError("cal_eam_forces()","MPI gather dfrhodrho_col failure")
532      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
533   #endif
534 +    
535 +    
536 +  end subroutine calc_sc_preforce_Frho
537  
538  
539 <  end subroutine calc_eam_preforce_Frho
540 <
731 <
732 <
733 <
734 <  !! Does EAM pairwise Force calculation.  
735 <  subroutine do_eam_pair(atom1, atom2, d, rij, r2, sw, vpair, fpair, &
539 >  !! Does Sutton-Chen  pairwise Force calculation.  
540 >  subroutine do_sc_pair(atom1, atom2, d, rij, r2, rcut, sw, vpair, fpair, &
541         pot, f, do_pot)
542      !Arguments    
543      integer, intent(in) ::  atom1, atom2
544 <    real( kind = dp ), intent(in) :: rij, r2
544 >    real( kind = dp ), intent(in) :: rij, r2, rcut
545      real( kind = dp ) :: pot, sw, vpair
546      real( kind = dp ), dimension(3,nLocal) :: f
547      real( kind = dp ), intent(in), dimension(3) :: d
# Line 745 | Line 550 | contains
550      logical, intent(in) :: do_pot
551  
552      real( kind = dp ) :: drdx,drdy,drdz
553 <    real( kind = dp ) :: d2
554 <    real( kind = dp ) :: phab,pha,dvpdr,d2vpdrdr
750 <    real( kind = dp ) :: rha,drha,d2rha, dpha
751 <    real( kind = dp ) :: rhb,drhb,d2rhb, dphb
553 >    real( kind = dp ) :: dvpdr
554 >    real( kind = dp ) :: drhodr
555      real( kind = dp ) :: dudr
556 <    real( kind = dp ) :: rci,rcj
556 >    real( kind = dp ) :: rcij
557      real( kind = dp ) :: drhoidr,drhojdr
755    real( kind = dp ) :: d2rhoidrdr
756    real( kind = dp ) :: d2rhojdrdr
558      real( kind = dp ) :: Fx,Fy,Fz
559      real( kind = dp ) :: r,d2pha,phb,d2phb
560 <
560 >    real( kind = dp ) :: pot_temp,vptmp
561 >    real( kind = dp ) :: epsilonij,aij,nij,mij,vcij
562      integer :: id1,id2
563      integer  :: mytype_atom1
564      integer  :: mytype_atom2
# Line 765 | Line 567 | contains
567  
568      ! write(*,*) "Frho: ", Frho(atom1)
569  
570 <    phab = 0.0E0_DP
570 >
571      dvpdr = 0.0E0_DP
770    d2vpdrdr = 0.0E0_DP
572  
772    if (rij .lt. EAM_rcut) then
573  
574   #ifdef IS_MPI
575         atid1 = atid_row(atom1)
# Line 779 | Line 579 | contains
579         atid2 = atid(atom2)
580   #endif
581  
582 <       mytype_atom1 = EAMList%atidToEAMType(atid1)
583 <       mytype_atom2 = EAMList%atidTOEAMType(atid2)
582 >       mytype_atom1 = SCList%atidToSCType(atid1)
583 >       mytype_atom2 = SCList%atidTOSCType(atid2)
584  
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
585         drdx = d(1)/rij
586         drdy = d(2)/rij
587         drdz = d(3)/rij
588  
589 <       if (rij.lt.rci) then
590 <          call eam_splint(EAMList%EAMParams(mytype_atom1)%eam_nr, &
591 <               EAMList%EAMParams(mytype_atom1)%eam_rvals, &
592 <               EAMList%EAMParams(mytype_atom1)%eam_rho_r, &
593 <               EAMList%EAMParams(mytype_atom1)%eam_rho_r_pp, &
594 <               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
589 >                
590 >       epsilonij = MixingMap(mytype_atom1,mytype_atom2)%epsilon
591 >       aij       = MixingMap(mytype_atom1,mytype_atom2)%alpha
592 >       nij       = MixingMap(mytype_atom1,mytype_atom2)%n
593 >       mij       = MixingMap(mytype_atom1,mytype_atom2)%m
594 >       vcij      = MixingMap(mytype_atom1,mytype_atom2)%vpair_pot              
595  
596 <       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)
596 >       vptmp = epsilonij*((aij/r)**nij)
597  
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
598  
599 <       if (rij.lt.rci) then
600 <          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
599 >       dvpdr = -nij*vptmp/r
600 >       drhodr = -mij*((aij/r)**mij)/r
601  
602 <       if (rij.lt.rcj) then
603 <          phab = phab + 0.5E0_DP*(rha/rhb)*phb
604 <          dvpdr = dvpdr + 0.5E0_DP*((rha/rhb)*dphb + &
605 <               phb*((drha/rhb) - (rha*drhb/rhb/rhb)))
606 <          d2vpdrdr = d2vpdrdr + 0.5E0_DP*((rha/rhb)*d2phb + &
607 <               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
602 >      
603 >       dudr = drhodr*(dfrhodrho(atom1)+dfrhodrho(atom2)) &
604 >            + dvpdr
605 >      
606 >       pot_temp = vptmp + vcij
607 >
608  
845       drhoidr = drha
846       drhojdr = drhb
847
848       d2rhoidrdr = d2rha
849       d2rhojdrdr = d2rhb
850
851
609   #ifdef IS_MPI
610 <       dudr = drhojdr*dfrhodrho_row(atom1)+drhoidr*dfrhodrho_col(atom2) &
610 >       dudr = drhodr*(dfrhodrho_row(atom1)+dfrhodrho_col(atom2)) &
611              + dvpdr
612  
613   #else
614 <       dudr = drhojdr*dfrhodrho(atom1)+drhoidr*dfrhodrho(atom2) &
614 >       dudr = drhodr*(dfrhodrho(atom1)+dfrhodrho(atom2)) &
615              + dvpdr
859       ! write(*,*) "Atom1,Atom2, dfrhodrho(atom1) dfrhodrho(atom2): ", atom1,atom2,dfrhodrho(atom1),dfrhodrho(atom2)
616   #endif
617  
618 +
619         fx = dudr * drdx
620         fy = dudr * drdy
621         fz = dudr * drdz
# Line 866 | Line 623 | contains
623  
624   #ifdef IS_MPI
625         if (do_pot) then
626 <          pot_Row(METALLIC_POT,atom1) = pot_Row(METALLIC_POT,atom1) + phab*0.5
627 <          pot_Col(METALLIC_POT,atom2) = pot_Col(METALLIC_POT,atom2) + phab*0.5
626 >          pot_Row(METALLIC_POT,atom1) = pot_Row(METALLIC_POT,atom1) + (pot_temp)*0.5
627 >          pot_Col(METALLIC_POT,atom2) = pot_Col(METALLIC_POT,atom2) + (pot_temp)*0.5
628         end if
629  
630         f_Row(1,atom1) = f_Row(1,atom1) + fx
# Line 880 | Line 637 | contains
637   #else
638  
639         if(do_pot) then
640 <          pot = pot + phab
640 >          pot = pot + pot_temp
641         end if
642  
643         f(1,atom1) = f(1,atom1) + fx
# Line 892 | Line 649 | contains
649         f(3,atom2) = f(3,atom2) - fz
650   #endif
651  
652 <       vpair = vpair + phab
652 >      
653   #ifdef IS_MPI
654         id1 = AtomRowToGlobal(atom1)
655         id2 = AtomColToGlobal(atom2)
# Line 909 | Line 666 | contains
666  
667         endif
668  
912       if (nmflag) then
669  
670 <          drhoidr = drha
915 <          drhojdr = drhb
916 <          d2rhoidrdr = d2rha
917 <          d2rhojdrdr = d2rhb
670 >  end subroutine do_sc_pair
671  
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)
672  
926 #else
673  
674 <          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
674 > end module suttonchen

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines