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 2401 by chuckv, Tue Nov 1 18:29:57 2005 UTC vs.
Revision 2756 by gezelter, Wed May 17 15:37:15 2006 UTC

# Line 44 | Line 44 | module suttonchen
44  
45  
46   module suttonchen
47 +  use definitions
48    use simulation
49    use force_globals
50    use status
51    use atype_module
52    use vector_class
53 +  use fForceOptions
54 +  use interpolation
55   #ifdef IS_MPI
56    use mpiSimulation
57   #endif
# Line 57 | Line 60 | module suttonchen
60   #define __FORTRAN90
61   #include "UseTheForce/DarkSide/fInteractionMap.h"
62  
63 <  INTEGER, PARAMETER :: DP = selected_real_kind(15)
63 >  !! number of points for the spline approximations
64 >  INTEGER, PARAMETER :: np = 3000
65  
66    logical, save :: SC_FF_initialized = .false.
67    integer, save :: SC_Mixing_Policy
68    real(kind = dp), save :: SC_rcut
69    logical, save :: haveRcut = .false.
70 +  logical, save :: haveMixingMap = .false.
71 +  logical, save :: useGeometricDistanceMixing = .false.
72 +  logical, save :: cleanArrays = .true.
73 +  logical, save :: arraysAllocated = .false.
74  
75 +
76    character(len = statusMsgSize) :: errMesg
77 <  integer :: eam_err
77 >  integer :: sc_err
78  
79    character(len = 200) :: errMsg
80    character(len=*), parameter :: RoutineName =  "Sutton-Chen MODULE"
81 <  !! Logical that determines if eam arrays should be zeroed
73 <  logical :: cleanme = .true.
74 <  logical :: nmflag  = .false.
75 <
76 <
81 >  
82    type, private :: SCtype
83 <     integer           :: atid      
84 <     real(kind=dp)     :: c
85 <     real(kind=dp)     :: m
86 <     real(kind=dp)     :: n
87 <     real(kind=dp)     :: alpha
88 <     real(kind=dp)     :: epsilon
83 >     integer       :: atid      
84 >     real(kind=dp) :: c
85 >     real(kind=dp) :: m
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  
86
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
97 <  real( kind = dp), dimension(:), allocatable :: d2frhodrhodrho
93 <
94 <
97 >  
98    !! Arrays for MPI storage
99   #ifdef IS_MPI
100    real( kind = dp),save, dimension(:), allocatable :: dfrhodrho_col
# Line 101 | Line 104 | module suttonchen
104    real( kind = dp),save, dimension(:), allocatable :: rho_row
105    real( kind = dp),save, dimension(:), allocatable :: rho_col
106    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
107   #endif
108  
109    type, private :: SCTypeList
110       integer           :: nSCTypes = 0
111 <     integer           :: currentSCtype = 0
112 <
113 <     type (SCtype), pointer  :: SCtypes(:) => null()
113 <     integer, pointer         :: atidToSCtype(:) => null()
111 >     integer           :: currentSCtype = 0    
112 >     type (SCtype), pointer :: SCtypes(:) => null()
113 >     integer, pointer       :: atidToSCtype(:) => null()
114    end type SCTypeList
115  
116
116    type (SCTypeList), save :: SCList
117  
118 <  !! standard eam stuff  
118 >  type:: MixParameters
119 >     real(kind=DP) :: alpha
120 >     real(kind=DP) :: epsilon
121 >     real(kind=DP) :: m
122 >     real(Kind=DP) :: n
123 >     real(kind=dp) :: rCut
124 >     real(kind=dp) :: vCut
125 >     logical       :: rCutWasSet = .false.
126 >     type(cubicSpline) :: V
127 >     type(cubicSpline) :: phi
128 >  end type MixParameters
129  
130 +  type(MixParameters), dimension(:,:), allocatable :: MixingMap
131  
122  public :: init_SC_FF
132    public :: setCutoffSC
133    public :: do_SC_pair
134    public :: newSCtype
135    public :: calc_SC_prepair_rho
136 +  public :: calc_SC_preforce_Frho
137    public :: clean_SC
138    public :: destroySCtypes
139    public :: getSCCut
140 + ! public :: setSCDefaultCutoff
141 + ! public :: setSCUniformCutoff
142 +
143  
144   contains
145  
146  
147 <  subroutine newEAMtype(lattice_constant,eam_nrho,eam_drho,eam_nr,&
148 <       eam_dr,rcut,eam_Z_r,eam_rho_r,eam_F_rho,&
149 <       c_ident,status)
150 <    real (kind = dp )                      :: lattice_constant
151 <    integer                                :: eam_nrho
152 <    real (kind = dp )                      :: eam_drho
140 <    integer                                :: eam_nr
141 <    real (kind = dp )                      :: eam_dr
142 <    real (kind = dp )                      :: rcut
143 <    real (kind = dp ), dimension(eam_nr)   :: eam_Z_r
144 <    real (kind = dp ), dimension(eam_nr)   :: eam_rho_r
145 <    real (kind = dp ), dimension(eam_nrho) :: eam_F_rho
147 >  subroutine newSCtype(c_ident,c,m,n,alpha,epsilon,status)
148 >    real (kind = dp )                      :: c ! Density Scaling
149 >    real (kind = dp )                      :: m ! Density Exponent
150 >    real (kind = dp )                      :: n ! Pair Potential Exponent
151 >    real (kind = dp )                      :: alpha ! Length Scaling
152 >    real (kind = dp )                      :: epsilon ! Energy Scaling
153      integer                                :: c_ident
154      integer                                :: status
155 <
149 <    integer                                :: nAtypes,nEAMTypes,myATID
155 >    integer                                :: nAtypes,nSCTypes,myATID
156      integer                                :: maxVals
157      integer                                :: alloc_stat
158      integer                                :: current
# Line 156 | Line 162 | contains
162  
163  
164      !! Assume that atypes has already been set and get the total number of types in atypes
159    !! Also assume that every member of atypes is a EAM model.
165  
166  
167      ! check to see if this is the first time into
168 <    if (.not.associated(EAMList%EAMParams)) then
169 <       call getMatchingElementList(atypes, "is_EAM", .true., nEAMtypes, MatchList)
170 <       EAMList%n_eam_types = nEAMtypes
171 <       allocate(EAMList%EAMParams(nEAMTypes))
168 >    if (.not.associated(SCList%SCTypes)) then
169 >       call getMatchingElementList(atypes, "is_SC", .true., nSCtypes, MatchList)
170 >       SCList%nSCtypes = nSCtypes
171 >       allocate(SCList%SCTypes(nSCTypes))
172         nAtypes = getSize(atypes)
173 <       allocate(EAMList%atidToEAMType(nAtypes))
173 >       allocate(SCList%atidToSCType(nAtypes))
174      end if
175  
176 <    EAMList%currentAddition = EAMList%currentAddition + 1
177 <    current = EAMList%currentAddition
176 >    SCList%currentSCType = SCList%currentSCType + 1
177 >    current = SCList%currentSCType
178  
179      myATID =  getFirstMatchingElement(atypes, "c_ident", c_ident)
180 <    EAMList%atidToEAMType(myATID) = current
176 <
177 <    call allocate_EAMType(eam_nrho,eam_nr,EAMList%EAMParams(current),stat=alloc_stat)
178 <    if (alloc_stat /= 0) then
179 <       status = -1
180 <       return
181 <    end if
182 <
180 >    SCList%atidToSCType(myATID) = current
181    
182 <    EAMList%EAMParams(current)%eam_atype    = c_ident
183 <    EAMList%EAMParams(current)%eam_lattice  = lattice_constant
184 <    EAMList%EAMParams(current)%eam_nrho     = eam_nrho
185 <    EAMList%EAMParams(current)%eam_drho     = eam_drho
186 <    EAMList%EAMParams(current)%eam_nr       = eam_nr
187 <    EAMList%EAMParams(current)%eam_dr       = eam_dr
188 <    EAMList%EAMParams(current)%eam_rcut     = rcut
191 <    EAMList%EAMParams(current)%eam_Z_r      = eam_Z_r
192 <    EAMList%EAMParams(current)%eam_rho_r    = eam_rho_r
193 <    EAMList%EAMParams(current)%eam_F_rho    = eam_F_rho
194 <
195 <  end subroutine newEAMtype
182 >    SCList%SCTypes(current)%atid         = c_ident
183 >    SCList%SCTypes(current)%alpha        = alpha
184 >    SCList%SCTypes(current)%c            = c
185 >    SCList%SCTypes(current)%m            = m
186 >    SCList%SCTypes(current)%n            = n
187 >    SCList%SCTypes(current)%epsilon      = epsilon
188 >  end subroutine newSCtype
189  
190 +  
191 +  subroutine destroySCTypes()
192 +    if (associated(SCList%SCtypes)) then
193 +       deallocate(SCList%SCTypes)
194 +       SCList%SCTypes=>null()
195 +    end if
196 +    if (associated(SCList%atidToSCtype)) then
197 +       deallocate(SCList%atidToSCtype)
198 +       SCList%atidToSCtype=>null()
199 +    end if
200 + ! Reset Capacity
201 +    SCList%nSCTypes = 0
202 +    SCList%currentSCtype=0
203  
204 <  ! kills all eam types entered and sets simulation to uninitalized
199 <  subroutine destroyEAMtypes()
200 <    integer :: i
201 <    type(EAMType), pointer :: tempEAMType=>null()
204 >  end subroutine destroySCTypes
205  
206 <    do i = 1, EAMList%n_eam_types
204 <       tempEAMType => eamList%EAMParams(i)
205 <       call deallocate_EAMType(tempEAMType)
206 <    end do
207 <    if(associated( eamList%EAMParams)) deallocate( eamList%EAMParams)
208 <    eamList%EAMParams => null()
209 <
210 <    eamList%n_eam_types = 0
211 <    eamList%currentAddition = 0
212 <
213 <  end subroutine destroyEAMtypes
214 <
215 <  function getEAMCut(atomID) result(cutValue)
206 >  function getSCCut(atomID) result(cutValue)
207      integer, intent(in) :: atomID
208 <    integer :: eamID
208 >    integer :: scID
209      real(kind=dp) :: cutValue
210      
211 <    eamID = EAMList%atidToEAMType(atomID)
212 <    cutValue = EAMList%EAMParams(eamID)%eam_rcut
213 <  end function getEAMCut
211 >    scID = SCList%atidToSCType(atomID)
212 >    cutValue = 2.0_dp * SCList%SCTypes(scID)%alpha
213 >  end function getSCCut
214  
215 <  subroutine init_EAM_FF(status)
216 <    integer :: status
217 <    integer :: i,j
218 <    real(kind=dp) :: current_rcut_max
219 <    integer :: alloc_stat
229 <    integer :: number_r, number_rho
215 >  subroutine createMixingMap()
216 >    integer :: nSCtypes, i, j, k
217 >    real ( kind = dp ) :: e1, e2, m1, m2, alpha1, alpha2, n1, n2
218 >    real ( kind = dp ) :: epsilon, m, n, alpha, rCut, vCut, dr, r
219 >    real ( kind = dp ), dimension(np) :: rvals, vvals, phivals
220  
221 <
222 <    status = 0
233 <    if (EAMList%currentAddition == 0) then
234 <       call handleError("init_EAM_FF","No members in EAMList")
235 <       status = -1
221 >    if (SCList%currentSCtype == 0) then
222 >       call handleError("SuttonChen", "No members in SCMap")
223         return
224      end if
225  
226 +    nSCtypes = SCList%nSCtypes
227  
228 <    do i = 1, EAMList%currentAddition
228 >    if (.not. allocated(MixingMap)) then
229 >       allocate(MixingMap(nSCtypes, nSCtypes))
230 >    endif
231 >    useGeometricDistanceMixing = usesGeometricDistanceMixing()
232 >    do i = 1, nSCtypes
233  
234 <       ! Build array of r values
234 >       e1 = SCList%SCtypes(i)%epsilon
235 >       m1 = SCList%SCtypes(i)%m
236 >       n1 = SCList%SCtypes(i)%n
237 >       alpha1 = SCList%SCtypes(i)%alpha
238  
239 <       do j = 1,EAMList%EAMParams(i)%eam_nr
240 <          EAMList%EAMParams(i)%eam_rvals(j) = &
241 <               real(j-1,kind=dp)* &
242 <               EAMList%EAMParams(i)%eam_dr
243 <       end do
244 <       ! Build array of rho values
250 <       do j = 1,EAMList%EAMParams(i)%eam_nrho
251 <          EAMList%EAMParams(i)%eam_rhovals(j) = &
252 <               real(j-1,kind=dp)* &
253 <               EAMList%EAMParams(i)%eam_drho
254 <       end do
255 <       ! convert from eV to kcal / mol:
256 <       EAMList%EAMParams(i)%eam_F_rho = EAMList%EAMParams(i)%eam_F_rho * 23.06054E0_DP
239 >       do j = 1, nSCtypes
240 >          
241 >          e2 = SCList%SCtypes(j)%epsilon
242 >          m2 = SCList%SCtypes(j)%m
243 >          n2 = SCList%SCtypes(j)%n
244 >          alpha2 = SCList%SCtypes(j)%alpha
245  
246 <       ! precompute the pair potential and get it into kcal / mol:
247 <       EAMList%EAMParams(i)%eam_phi_r(1) = 0.0E0_DP
248 <       do j = 2, EAMList%EAMParams(i)%eam_nr
249 <          EAMList%EAMParams(i)%eam_phi_r(j) = (EAMList%EAMParams(i)%eam_Z_r(j)**2)/EAMList%EAMParams(i)%eam_rvals(j)
250 <          EAMList%EAMParams(i)%eam_phi_r(j) =  EAMList%EAMParams(i)%eam_phi_r(j)*331.999296E0_DP
251 <       enddo
252 <    end do
246 >          if (useGeometricDistanceMixing) then
247 >             alpha = sqrt(alpha1 * alpha2) !SC formulation
248 >          else
249 >             alpha = 0.5_dp * (alpha1 + alpha2) ! Goddard formulation
250 >          endif
251 >          rcut = 2.0_dp * alpha
252 >          epsilon = sqrt(e1 * e2)
253 >          m = 0.5_dp*(m1+m2)
254 >          n = 0.5_dp*(n1+n2)
255  
256 +          dr = (rCut) / dble(np-1)
257 +          rvals(1) = 0.0_dp
258 +          vvals(1) = 0.0_dp
259 +          phivals(1) = 0.0_dp
260  
261 <    do i = 1,  EAMList%currentAddition
262 <       number_r   = EAMList%EAMParams(i)%eam_nr
263 <       number_rho = EAMList%EAMParams(i)%eam_nrho
261 >          do k = 2, np
262 >             r = dble(k-1)*dr
263 >             rvals(k) = r
264 >             vvals(k) = epsilon*((alpha/r)**n)
265 >             phivals(k) = (alpha/r)**m
266 >          enddo
267  
268 <       call eam_spline(number_r, EAMList%EAMParams(i)%eam_rvals, &
272 <            EAMList%EAMParams(i)%eam_rho_r, &
273 <            EAMList%EAMParams(i)%eam_rho_r_pp, &
274 <            0.0E0_DP, 0.0E0_DP, 'N')
275 <       call eam_spline(number_r, EAMList%EAMParams(i)%eam_rvals, &
276 <            EAMList%EAMParams(i)%eam_Z_r, &
277 <            EAMList%EAMParams(i)%eam_Z_r_pp, &
278 <            0.0E0_DP, 0.0E0_DP, 'N')
279 <       call eam_spline(number_rho, EAMList%EAMParams(i)%eam_rhovals, &
280 <            EAMList%EAMParams(i)%eam_F_rho, &
281 <            EAMList%EAMParams(i)%eam_F_rho_pp, &
282 <            0.0E0_DP, 0.0E0_DP, 'N')
283 <       call eam_spline(number_r, EAMList%EAMParams(i)%eam_rvals, &
284 <            EAMList%EAMParams(i)%eam_phi_r, &
285 <            EAMList%EAMParams(i)%eam_phi_r_pp, &
286 <            0.0E0_DP, 0.0E0_DP, 'N')
287 <    enddo
268 >          vCut = epsilon*((alpha/rCut)**n)
269  
270 <    !       current_rcut_max = EAMList%EAMParams(1)%eam_rcut
271 <    !! find the smallest rcut for any eam atype
291 <    !       do i = 2, EAMList%currentAddition
292 <    !          current_rcut_max =max(current_rcut_max,EAMList%EAMParams(i)%eam_rcut)
293 <    !       end do
270 >          call newSpline(MixingMap(i,j)%V, rvals, vvals, .true.)
271 >          call newSpline(MixingMap(i,j)%phi, rvals, phivals, .true.)
272  
273 <    !       EAM_rcut = current_rcut_max
274 <    !       EAM_rcut_orig = current_rcut_max
275 <    !       do i = 1, EAMList%currentAddition
276 <    !          EAMList%EAMParam(i)s%eam_atype_map(eam_atype(i)) = i
277 <    !       end do
278 <    !! Allocate arrays for force calculation
273 >          MixingMap(i,j)%epsilon = epsilon
274 >          MixingMap(i,j)%m = m
275 >          MixingMap(i,j)%n = n
276 >          MixingMap(i,j)%alpha = alpha
277 >          MixingMap(i,j)%rCut = rcut
278 >          MixingMap(i,j)%vCut = vCut
279 >       enddo
280 >    enddo
281 >    
282 >    haveMixingMap = .true.
283 >    
284 >  end subroutine createMixingMap
285 >  
286  
302    call allocateEAM(alloc_stat)
303    if (alloc_stat /= 0 ) then
304       write(*,*) "allocateEAM failed"
305       status = -1
306       return
307    endif
308
309  end subroutine init_EAM_FF
310
287    !! routine checks to see if array is allocated, deallocates array if allocated
288    !! and then creates the array to the required size
289 <  subroutine allocateEAM(status)
290 <    integer, intent(out) :: status
289 >  subroutine allocateSC()
290 >    integer :: status
291  
292   #ifdef IS_MPI
293      integer :: nAtomsInRow
# Line 319 | Line 295 | contains
295   #endif
296      integer :: alloc_stat
297  
298 <
298 >    
299      status = 0
300   #ifdef IS_MPI
301      nAtomsInRow = getNatomsInRow(plan_atom_row)
# Line 328 | Line 304 | contains
304  
305      if (allocated(frho)) deallocate(frho)
306      allocate(frho(nlocal),stat=alloc_stat)
307 <    if (alloc_stat /= 0) then
307 >    if (alloc_stat /= 0) then
308         status = -1
333       return
309      end if
310 +
311      if (allocated(rho)) deallocate(rho)
312      allocate(rho(nlocal),stat=alloc_stat)
313      if (alloc_stat /= 0) then
314         status = -1
339       return
315      end if
316  
317      if (allocated(dfrhodrho)) deallocate(dfrhodrho)
318      allocate(dfrhodrho(nlocal),stat=alloc_stat)
319      if (alloc_stat /= 0) then
320         status = -1
346       return
321      end if
322  
349    if (allocated(d2frhodrhodrho)) deallocate(d2frhodrhodrho)
350    allocate(d2frhodrhodrho(nlocal),stat=alloc_stat)
351    if (alloc_stat /= 0) then
352       status = -1
353       return
354    end if
355
323   #ifdef IS_MPI
324  
325      if (allocated(rho_tmp)) deallocate(rho_tmp)
326      allocate(rho_tmp(nlocal),stat=alloc_stat)
327      if (alloc_stat /= 0) then
328         status = -1
362       return
329      end if
330  
331  
# Line 367 | Line 333 | contains
333      allocate(frho_row(nAtomsInRow),stat=alloc_stat)
334      if (alloc_stat /= 0) then
335         status = -1
370       return
336      end if
337      if (allocated(rho_row)) deallocate(rho_row)
338      allocate(rho_row(nAtomsInRow),stat=alloc_stat)
339      if (alloc_stat /= 0) then
340         status = -1
376       return
341      end if
342      if (allocated(dfrhodrho_row)) deallocate(dfrhodrho_row)
343      allocate(dfrhodrho_row(nAtomsInRow),stat=alloc_stat)
344      if (alloc_stat /= 0) then
345         status = -1
382       return
346      end if
384    if (allocated(d2frhodrhodrho_row)) deallocate(d2frhodrhodrho_row)
385    allocate(d2frhodrhodrho_row(nAtomsInRow),stat=alloc_stat)
386    if (alloc_stat /= 0) then
387       status = -1
388       return
389    end if
347  
348  
349      ! Now do column arrays
# Line 395 | Line 352 | contains
352      allocate(frho_col(nAtomsInCol),stat=alloc_stat)
353      if (alloc_stat /= 0) then
354         status = -1
398       return
355      end if
356      if (allocated(rho_col)) deallocate(rho_col)
357      allocate(rho_col(nAtomsInCol),stat=alloc_stat)
358      if (alloc_stat /= 0) then
359         status = -1
404       return
360      end if
361      if (allocated(dfrhodrho_col)) deallocate(dfrhodrho_col)
362      allocate(dfrhodrho_col(nAtomsInCol),stat=alloc_stat)
363      if (alloc_stat /= 0) then
364         status = -1
410       return
365      end if
412    if (allocated(d2frhodrhodrho_col)) deallocate(d2frhodrhodrho_col)
413    allocate(d2frhodrhodrho_col(nAtomsInCol),stat=alloc_stat)
414    if (alloc_stat /= 0) then
415       status = -1
416       return
417    end if
366  
367   #endif
368 +    if (status == -1) then
369 +       call handleError("SuttonChen:allocateSC","Error in allocating SC arrays")
370 +    end if
371 +    arraysAllocated = .true.
372 +  end subroutine allocateSC
373  
374 <  end subroutine allocateEAM
422 <
423 <  !! C sets rcut to be the largest cutoff of any atype
424 <  !! present in this simulation. Doesn't include all atypes
425 <  !! sim knows about, just those in the simulation.
426 <  subroutine setCutoffEAM(rcut, status)
374 >  subroutine setCutoffSC(rcut)
375      real(kind=dp) :: rcut
376 <    integer :: status
377 <    status = 0
378 <
379 <    EAM_rcut = rcut
380 <
381 <  end subroutine setCutoffEAM
382 <
435 <
436 <
437 <  subroutine clean_EAM()
438 <
376 >    SC_rcut = rcut
377 >  end subroutine setCutoffSC
378 >  
379 >  !! This array allocates module arrays if needed and builds mixing map.
380 >  subroutine clean_SC()
381 >    if (.not.arraysAllocated) call allocateSC()
382 >    if (.not.haveMixingMap) call createMixingMap()
383      ! clean non-IS_MPI first
384      frho = 0.0_dp
385      rho  = 0.0_dp
# Line 450 | Line 394 | contains
394      dfrhodrho_row = 0.0_dp
395      dfrhodrho_col = 0.0_dp
396   #endif
397 <  end subroutine clean_EAM
397 >  end subroutine clean_SC
398  
455
456
457  subroutine allocate_EAMType(eam_n_rho,eam_n_r,thisEAMType,stat)
458    integer, intent(in)          :: eam_n_rho
459    integer, intent(in)          :: eam_n_r
460    type (EAMType)               :: thisEAMType
461    integer, optional   :: stat
462    integer             :: alloc_stat
463
464
465
466    if (present(stat)) stat = 0
467
468    allocate(thisEAMType%eam_rvals(eam_n_r),stat=alloc_stat)  
469    if (alloc_stat /= 0 ) then
470       if (present(stat)) stat = -1
471       return
472    end if
473    allocate(thisEAMType%eam_rhovals(eam_n_rho),stat=alloc_stat)  
474    if (alloc_stat /= 0 ) then
475       if (present(stat)) stat = -1
476       return
477    end if
478    allocate(thisEAMType%eam_F_rho(eam_n_rho),stat=alloc_stat)  
479    if (alloc_stat /= 0 ) then
480       if (present(stat)) stat = -1
481       return
482    end if
483    allocate(thisEAMType%eam_Z_r(eam_n_r),stat=alloc_stat)        
484    if (alloc_stat /= 0 ) then
485       if (present(stat)) stat = -1
486       return
487    end if
488    allocate(thisEAMType%eam_rho_r(eam_n_r),stat=alloc_stat)      
489    if (alloc_stat /= 0 ) then
490       if (present(stat)) stat = -1
491       return
492    end if
493    allocate(thisEAMType%eam_phi_r(eam_n_r),stat=alloc_stat)      
494    if (alloc_stat /= 0 ) then
495       if (present(stat)) stat = -1
496       return
497    end if
498    allocate(thisEAMType%eam_F_rho_pp(eam_n_rho),stat=alloc_stat)  
499    if (alloc_stat /= 0 ) then
500       if (present(stat)) stat = -1
501       return
502    end if
503    allocate(thisEAMType%eam_Z_r_pp(eam_n_r),stat=alloc_stat)  
504    if (alloc_stat /= 0 ) then
505       if (present(stat)) stat = -1
506       return
507    end if
508    allocate(thisEAMType%eam_rho_r_pp(eam_n_r),stat=alloc_stat)  
509    if (alloc_stat /= 0 ) then
510       if (present(stat)) stat = -1
511       return
512    end if
513    allocate(thisEAMType%eam_phi_r_pp(eam_n_r),stat=alloc_stat)
514    if (alloc_stat /= 0 ) then
515       if (present(stat)) stat = -1
516       return
517    end if
518
519
520  end subroutine allocate_EAMType
521
522
523  subroutine deallocate_EAMType(thisEAMType)
524    type (EAMtype), pointer :: thisEAMType
525
526    ! free Arrays in reverse order of allocation...
527    if(associated(thisEAMType%eam_phi_r_pp)) deallocate(thisEAMType%eam_phi_r_pp)      
528    if(associated(thisEAMType%eam_rho_r_pp)) deallocate(thisEAMType%eam_rho_r_pp)  
529    if(associated(thisEAMType%eam_Z_r_pp)) deallocate(thisEAMType%eam_Z_r_pp)  
530    if(associated(thisEAMType%eam_F_rho_pp)) deallocate(thisEAMType%eam_F_rho_pp)  
531    if(associated(thisEAMType%eam_phi_r)) deallocate(thisEAMType%eam_phi_r)      
532    if(associated(thisEAMType%eam_rho_r)) deallocate(thisEAMType%eam_rho_r)      
533    if(associated(thisEAMType%eam_Z_r)) deallocate(thisEAMType%eam_Z_r)  
534    if(associated(thisEAMType%eam_F_rho)) deallocate(thisEAMType%eam_F_rho)
535    if(associated(thisEAMType%eam_rhovals)) deallocate(thisEAMType%eam_rhovals)
536    if(associated(thisEAMType%eam_rvals)) deallocate(thisEAMType%eam_rvals)
537
538  end subroutine deallocate_EAMType
539
399    !! Calculates rho_r
400 <  subroutine calc_eam_prepair_rho(atom1,atom2,d,r,rijsq)
400 >  subroutine calc_sc_prepair_rho(atom1, atom2, d, r, rijsq, rcut)
401      integer :: atom1,atom2
402      real(kind = dp), dimension(3) :: d
403      real(kind = dp), intent(inout)               :: r
404 <    real(kind = dp), intent(inout)               :: rijsq
404 >    real(kind = dp), intent(inout)               :: rijsq, rcut
405      ! value of electron density rho do to atom i at atom j
406      real(kind = dp) :: rho_i_at_j
407      ! value of electron density rho do to atom j at atom i
408      real(kind = dp) :: rho_j_at_i
409  
410      ! we don't use the derivatives, dummy variables
411 <    real( kind = dp) :: drho,d2rho
412 <    integer :: eam_err
411 >    real( kind = dp) :: drho
412 >    integer :: sc_err
413      
414      integer :: atid1,atid2 ! Global atid    
415      integer :: myid_atom1 ! EAM atid
# Line 559 | Line 418 | contains
418  
419      ! check to see if we need to be cleaned at the start of a force loop
420  
421 +    if (cleanArrays) call clean_SC()
422 +    cleanArrays = .false.
423  
563
564
424   #ifdef IS_MPI
425      Atid1 = Atid_row(Atom1)
426      Atid2 = Atid_col(Atom2)
# Line 570 | Line 429 | contains
429      Atid2 = Atid(Atom2)
430   #endif
431  
432 <    Myid_atom1 = Eamlist%atidtoeamtype(Atid1)
433 <    Myid_atom2 = Eamlist%atidtoeamtype(Atid2)
432 >    Myid_atom1 = SCList%atidtoSCtype(Atid1)
433 >    Myid_atom2 = SCList%atidtoSCtype(Atid2)
434 >    
435 >    call lookupUniformSpline(MixingMap(myid_atom1,myid_atom2)%phi, r, &
436 >         rho_i_at_j)
437 >    rho_j_at_i = rho_i_at_j
438  
576    if (r.lt.EAMList%EAMParams(myid_atom1)%eam_rcut) then
577
578
579
580       call eam_splint(EAMList%EAMParams(myid_atom1)%eam_nr, &
581            EAMList%EAMParams(myid_atom1)%eam_rvals, &
582            EAMList%EAMParams(myid_atom1)%eam_rho_r, &
583            EAMList%EAMParams(myid_atom1)%eam_rho_r_pp, &
584            r, rho_i_at_j,drho,d2rho)
585
586
587
439   #ifdef  IS_MPI
440 <       rho_col(atom2) = rho_col(atom2) + rho_i_at_j
440 >    rho_col(atom2) = rho_col(atom2) + rho_i_at_j
441 >    rho_row(atom1) = rho_row(atom1) + rho_j_at_i
442   #else
443 <       rho(atom2) = rho(atom2) + rho_i_at_j
443 >    rho(atom2) = rho(atom2) + rho_i_at_j
444 >    rho(atom1) = rho(atom1) + rho_j_at_i
445   #endif
446 <             ! write(*,*) atom1,atom2,r,rho_i_at_j
447 <    endif
446 >    
447 >  end subroutine calc_sc_prepair_rho
448  
596    if (r.lt.EAMList%EAMParams(myid_atom2)%eam_rcut) then
597       call eam_splint(EAMList%EAMParams(myid_atom2)%eam_nr, &
598            EAMList%EAMParams(myid_atom2)%eam_rvals, &
599            EAMList%EAMParams(myid_atom2)%eam_rho_r, &
600            EAMList%EAMParams(myid_atom2)%eam_rho_r_pp, &
601            r, rho_j_at_i,drho,d2rho)
449  
450 <
451 <
605 <
606 < #ifdef  IS_MPI
607 <       rho_row(atom1) = rho_row(atom1) + rho_j_at_i
608 < #else
609 <       rho(atom1) = rho(atom1) + rho_j_at_i
610 < #endif
611 <    endif
612 <
613 <
614 <
615 <
616 <
617 <
618 <  end subroutine calc_eam_prepair_rho
619 <
620 <
621 <
622 <
623 <  !! Calculate the functional F(rho) for all local atoms
624 <  subroutine calc_eam_preforce_Frho(nlocal,pot)
450 >  !! Calculate the rho_a for all local atoms
451 >  subroutine calc_sc_preforce_Frho(nlocal,pot)
452      integer :: nlocal
453      real(kind=dp) :: pot
454      integer :: i,j
455      integer :: atom
629    real(kind=dp) :: U,U1,U2
456      integer :: atype1
457 <    integer :: me,atid1
458 <    integer :: n_rho_points
457 >    integer :: atid1
458 >    integer :: myid
459  
460 <
461 <    cleanme = .true.
636 <    !! Scatter the electron density from  pre-pair calculation back to local atoms
460 >    !! Scatter the electron density from  pre-pair calculation back to
461 >    !! local atoms
462   #ifdef IS_MPI
463 <    call scatter(rho_row,rho,plan_atom_row,eam_err)
464 <    if (eam_err /= 0 ) then
463 >    call scatter(rho_row,rho,plan_atom_row,sc_err)
464 >    if (sc_err /= 0 ) then
465         write(errMsg,*) " Error scattering rho_row into rho"
466         call handleError(RoutineName,errMesg)
467      endif
468 <    call scatter(rho_col,rho_tmp,plan_atom_col,eam_err)
469 <    if (eam_err /= 0 ) then
468 >    call scatter(rho_col,rho_tmp,plan_atom_col,sc_err)
469 >    if (sc_err /= 0 ) then
470         write(errMsg,*) " Error scattering rho_col into rho"
471         call handleError(RoutineName,errMesg)
472 +
473      endif
474  
475      rho(1:nlocal) = rho(1:nlocal) + rho_tmp(1:nlocal)
476   #endif
477 <
478 <
653 <
654 <    !! Calculate F(rho) and derivative
477 >    
478 >    !! Calculate F(rho) and derivative
479      do atom = 1, nlocal
480 <       atid1 = atid(atom)
481 <       me = eamList%atidToEAMtype(atid1)
482 <       n_rho_points = EAMList%EAMParams(me)%eam_nrho
659 <       !  Check to see that the density is not greater than the larges rho we have calculated
660 <       if (rho(atom) < EAMList%EAMParams(me)%eam_rhovals(n_rho_points)) then
661 <          call eam_splint(n_rho_points, &
662 <               EAMList%EAMParams(me)%eam_rhovals, &
663 <               EAMList%EAMParams(me)%eam_f_rho, &
664 <               EAMList%EAMParams(me)%eam_f_rho_pp, &
665 <               rho(atom), & ! Actual Rho
666 <               u, u1, u2)
667 <       else
668 <          ! Calculate F(rho with the largest available rho value
669 <          call eam_splint(n_rho_points, &
670 <               EAMList%EAMParams(me)%eam_rhovals, &
671 <               EAMList%EAMParams(me)%eam_f_rho, &
672 <               EAMList%EAMParams(me)%eam_f_rho_pp, &
673 <               EAMList%EAMParams(me)%eam_rhovals(n_rho_points), & ! Largest rho
674 <               u,u1,u2)
675 <       end if
480 >       Myid = SCList%atidtoSctype(Atid(atom))
481 >       frho(atom) = - SCList%SCTypes(Myid)%c * &
482 >            SCList%SCTypes(Myid)%epsilon * sqrt(rho(atom))
483  
484 +       dfrhodrho(atom) = 0.5_dp*frho(atom)/rho(atom)
485  
486 <       frho(atom) = u
679 <       dfrhodrho(atom) = u1
680 <       d2frhodrhodrho(atom) = u2
681 <       pot = pot + u
682 <
486 >       pot = pot + frho(atom)
487      enddo
488  
685
686
489   #ifdef IS_MPI
490      !! communicate f(rho) and derivatives back into row and column arrays
491 <    call gather(frho,frho_row,plan_atom_row, eam_err)
492 <    if (eam_err /=  0) then
491 >    call gather(frho,frho_row,plan_atom_row, sc_err)
492 >    if (sc_err /=  0) then
493         call handleError("cal_eam_forces()","MPI gather frho_row failure")
494      endif
495 <    call gather(dfrhodrho,dfrhodrho_row,plan_atom_row, eam_err)
496 <    if (eam_err /=  0) then
495 >    call gather(dfrhodrho,dfrhodrho_row,plan_atom_row, sc_err)
496 >    if (sc_err /=  0) then
497         call handleError("cal_eam_forces()","MPI gather dfrhodrho_row failure")
498      endif
499 <    call gather(frho,frho_col,plan_atom_col, eam_err)
500 <    if (eam_err /=  0) then
499 >    call gather(frho,frho_col,plan_atom_col, sc_err)
500 >    if (sc_err /=  0) then
501         call handleError("cal_eam_forces()","MPI gather frho_col failure")
502      endif
503 <    call gather(dfrhodrho,dfrhodrho_col,plan_atom_col, eam_err)
504 <    if (eam_err /=  0) then
503 >    call gather(dfrhodrho,dfrhodrho_col,plan_atom_col, sc_err)
504 >    if (sc_err /=  0) then
505         call handleError("cal_eam_forces()","MPI gather dfrhodrho_col failure")
506      endif
705
706
707
708
709
710    if (nmflag) then
711       call gather(d2frhodrhodrho,d2frhodrhodrho_row,plan_atom_row)
712       call gather(d2frhodrhodrho,d2frhodrhodrho_col,plan_atom_col)
713    endif
507   #endif
508 <
509 <
510 <  end subroutine calc_eam_preforce_Frho
511 <
512 <
513 <
721 <
722 <  !! Does EAM pairwise Force calculation.  
723 <  subroutine do_eam_pair(atom1, atom2, d, rij, r2, sw, vpair, fpair, &
508 >    
509 >    
510 >  end subroutine calc_sc_preforce_Frho  
511 >  
512 >  !! Does Sutton-Chen  pairwise Force calculation.  
513 >  subroutine do_sc_pair(atom1, atom2, d, rij, r2, rcut, sw, vpair, fpair, &
514         pot, f, do_pot)
515      !Arguments    
516      integer, intent(in) ::  atom1, atom2
517 <    real( kind = dp ), intent(in) :: rij, r2
517 >    real( kind = dp ), intent(in) :: rij, r2, rcut
518      real( kind = dp ) :: pot, sw, vpair
519      real( kind = dp ), dimension(3,nLocal) :: f
520      real( kind = dp ), intent(in), dimension(3) :: d
# Line 732 | Line 522 | contains
522  
523      logical, intent(in) :: do_pot
524  
525 <    real( kind = dp ) :: drdx,drdy,drdz
526 <    real( kind = dp ) :: d2
527 <    real( kind = dp ) :: phab,pha,dvpdr,d2vpdrdr
738 <    real( kind = dp ) :: rha,drha,d2rha, dpha
739 <    real( kind = dp ) :: rhb,drhb,d2rhb, dphb
525 >    real( kind = dp ) :: drdx, drdy, drdz
526 >    real( kind = dp ) :: dvpdr
527 >    real( kind = dp ) :: rhtmp, drhodr
528      real( kind = dp ) :: dudr
741    real( kind = dp ) :: rci,rcj
742    real( kind = dp ) :: drhoidr,drhojdr
743    real( kind = dp ) :: d2rhoidrdr
744    real( kind = dp ) :: d2rhojdrdr
529      real( kind = dp ) :: Fx,Fy,Fz
530 <    real( kind = dp ) :: r,d2pha,phb,d2phb
531 <
532 <    integer :: id1,id2
530 >    real( kind = dp ) :: pot_temp, vptmp
531 >    real( kind = dp ) :: rcij, vcij
532 >    integer :: id1, id2
533      integer  :: mytype_atom1
534      integer  :: mytype_atom2
535 <    integer  :: atid1,atid2
535 >    integer  :: atid1, atid2
536      !Local Variables
537 +    
538 +    cleanArrays = .true.
539  
754    ! write(*,*) "Frho: ", Frho(atom1)
755
756    phab = 0.0E0_DP
757    dvpdr = 0.0E0_DP
758    d2vpdrdr = 0.0E0_DP
759
760    if (rij .lt. EAM_rcut) then
761
540   #ifdef IS_MPI
541         atid1 = atid_row(atom1)
542         atid2 = atid_col(atom2)
# Line 767 | Line 545 | contains
545         atid2 = atid(atom2)
546   #endif
547  
548 <       mytype_atom1 = EAMList%atidToEAMType(atid1)
549 <       mytype_atom2 = EAMList%atidTOEAMType(atid2)
548 >       mytype_atom1 = SCList%atidToSCType(atid1)
549 >       mytype_atom2 = SCList%atidTOSCType(atid2)
550  
773
774       ! get cutoff for atom 1
775       rci = EAMList%EAMParams(mytype_atom1)%eam_rcut
776       ! get type specific cutoff for atom 2
777       rcj = EAMList%EAMParams(mytype_atom2)%eam_rcut
778
551         drdx = d(1)/rij
552         drdy = d(2)/rij
553         drdz = d(3)/rij
554 <
555 <       if (rij.lt.rci) then
556 <          call eam_splint(EAMList%EAMParams(mytype_atom1)%eam_nr, &
557 <               EAMList%EAMParams(mytype_atom1)%eam_rvals, &
558 <               EAMList%EAMParams(mytype_atom1)%eam_rho_r, &
559 <               EAMList%EAMParams(mytype_atom1)%eam_rho_r_pp, &
788 <               rij, rha,drha,d2rha)
789 <          !! Calculate Phi(r) for atom1.
790 <          call eam_splint(EAMList%EAMParams(mytype_atom1)%eam_nr, &
791 <               EAMList%EAMParams(mytype_atom1)%eam_rvals, &
792 <               EAMList%EAMParams(mytype_atom1)%eam_phi_r, &
793 <               EAMList%EAMParams(mytype_atom1)%eam_phi_r_pp, &
794 <               rij, pha,dpha,d2pha)
795 <       endif
796 <
797 <       if (rij.lt.rcj) then      
798 <          ! Calculate rho,drho and d2rho for atom1
799 <          call eam_splint(EAMList%EAMParams(mytype_atom2)%eam_nr, &
800 <               EAMList%EAMParams(mytype_atom2)%eam_rvals, &
801 <               EAMList%EAMParams(mytype_atom2)%eam_rho_r, &
802 <               EAMList%EAMParams(mytype_atom2)%eam_rho_r_pp, &
803 <               rij, rhb,drhb,d2rhb)
554 >                
555 >       rcij = MixingMap(mytype_atom1,mytype_atom2)%rCut
556 >       vcij = MixingMap(mytype_atom1,mytype_atom2)%vCut
557 >      
558 >       call lookupUniformSpline1d(MixingMap(mytype_atom1, mytype_atom2)%phi, &
559 >            rij, rhtmp, drhodr)
560  
561 <          !! Calculate Phi(r) for atom2.
562 <          call eam_splint(EAMList%EAMParams(mytype_atom2)%eam_nr, &
563 <               EAMList%EAMParams(mytype_atom2)%eam_rvals, &
808 <               EAMList%EAMParams(mytype_atom2)%eam_phi_r, &
809 <               EAMList%EAMParams(mytype_atom2)%eam_phi_r_pp, &
810 <               rij, phb,dphb,d2phb)
811 <       endif
812 <
813 <       if (rij.lt.rci) then
814 <          phab = phab + 0.5E0_DP*(rhb/rha)*pha
815 <          dvpdr = dvpdr + 0.5E0_DP*((rhb/rha)*dpha + &
816 <               pha*((drhb/rha) - (rhb*drha/rha/rha)))
817 <          d2vpdrdr = d2vpdrdr + 0.5E0_DP*((rhb/rha)*d2pha + &
818 <               2.0E0_DP*dpha*((drhb/rha) - (rhb*drha/rha/rha)) + &
819 <               pha*((d2rhb/rha) - 2.0E0_DP*(drhb*drha/rha/rha) + &
820 <               (2.0E0_DP*rhb*drha*drha/rha/rha/rha) - (rhb*d2rha/rha/rha)))
821 <       endif
822 <
823 <       if (rij.lt.rcj) then
824 <          phab = phab + 0.5E0_DP*(rha/rhb)*phb
825 <          dvpdr = dvpdr + 0.5E0_DP*((rha/rhb)*dphb + &
826 <               phb*((drha/rhb) - (rha*drhb/rhb/rhb)))
827 <          d2vpdrdr = d2vpdrdr + 0.5E0_DP*((rha/rhb)*d2phb + &
828 <               2.0E0_DP*dphb*((drha/rhb) - (rha*drhb/rhb/rhb)) + &
829 <               phb*((d2rha/rhb) - 2.0E0_DP*(drha*drhb/rhb/rhb) + &
830 <               (2.0E0_DP*rha*drhb*drhb/rhb/rhb/rhb) - (rha*d2rhb/rhb/rhb)))
831 <       endif
832 <
833 <       drhoidr = drha
834 <       drhojdr = drhb
835 <
836 <       d2rhoidrdr = d2rha
837 <       d2rhojdrdr = d2rhb
838 <
839 <
561 >       call lookupUniformSpline1d(MixingMap(mytype_atom1, mytype_atom2)%V, &
562 >            rij, vptmp, dvpdr)
563 >      
564   #ifdef IS_MPI
565 <       dudr = drhojdr*dfrhodrho_row(atom1)+drhoidr*dfrhodrho_col(atom2) &
842 <            + dvpdr
843 <
565 >       dudr = drhodr*(dfrhodrho_row(atom1) + dfrhodrho_col(atom2)) + dvpdr
566   #else
567 <       dudr = drhojdr*dfrhodrho(atom1)+drhoidr*dfrhodrho(atom2) &
846 <            + dvpdr
847 <       ! write(*,*) "Atom1,Atom2, dfrhodrho(atom1) dfrhodrho(atom2): ", atom1,atom2,dfrhodrho(atom1),dfrhodrho(atom2)
567 >       dudr = drhodr*(dfrhodrho(atom1)+ dfrhodrho(atom2)) + dvpdr
568   #endif
569 <
569 >              
570 >       pot_temp = vptmp - vcij
571 >
572         fx = dudr * drdx
573         fy = dudr * drdy
574         fz = dudr * drdz
575  
854
576   #ifdef IS_MPI
577         if (do_pot) then
578 <          pot_Row(METALLIC_POT,atom1) = pot_Row(METALLIC_POT,atom1) + phab*0.5
579 <          pot_Col(METALLIC_POT,atom2) = pot_Col(METALLIC_POT,atom2) + phab*0.5
578 >          pot_Row(METALLIC_POT,atom1) = pot_Row(METALLIC_POT,atom1) + (pot_temp)*0.5
579 >          pot_Col(METALLIC_POT,atom2) = pot_Col(METALLIC_POT,atom2) + (pot_temp)*0.5
580         end if
581  
582         f_Row(1,atom1) = f_Row(1,atom1) + fx
# Line 868 | Line 589 | contains
589   #else
590  
591         if(do_pot) then
592 <          pot = pot + phab
592 >          pot = pot + pot_temp
593         end if
594  
595         f(1,atom1) = f(1,atom1) + fx
# Line 880 | Line 601 | contains
601         f(3,atom2) = f(3,atom2) - fz
602   #endif
603  
604 <       vpair = vpair + phab
604 >      
605   #ifdef IS_MPI
606         id1 = AtomRowToGlobal(atom1)
607         id2 = AtomColToGlobal(atom2)
# Line 896 | Line 617 | contains
617            fpair(3) = fpair(3) + fz
618  
619         endif
620 <
621 <       if (nmflag) then
901 <
902 <          drhoidr = drha
903 <          drhojdr = drhb
904 <          d2rhoidrdr = d2rha
905 <          d2rhojdrdr = d2rhb
906 <
907 < #ifdef IS_MPI
908 <          d2 = d2vpdrdr + &
909 <               d2rhoidrdr*dfrhodrho_col(atom2) + &
910 <               d2rhojdrdr*dfrhodrho_row(atom1) + &
911 <               drhoidr*drhoidr*d2frhodrhodrho_col(atom2) + &
912 <               drhojdr*drhojdr*d2frhodrhodrho_row(atom1)
913 <
914 < #else
915 <
916 <          d2 = d2vpdrdr + &
917 <               d2rhoidrdr*dfrhodrho(atom2) + &
918 <               d2rhojdrdr*dfrhodrho(atom1) + &
919 <               drhoidr*drhoidr*d2frhodrhodrho(atom2) + &
920 <               drhojdr*drhojdr*d2frhodrhodrho(atom1)
921 < #endif
922 <       end if
923 <
924 <    endif
925 <  end subroutine do_eam_pair
926 <
927 <
928 <  subroutine eam_splint(nx, xa, ya, yppa, x, y, dy, d2y)
929 <
930 <    integer :: atype, nx, j
931 <    real( kind = DP ), dimension(:) :: xa
932 <    real( kind = DP ), dimension(:) :: ya
933 <    real( kind = DP ), dimension(:) :: yppa
934 <    real( kind = DP ) :: x, y
935 <    real( kind = DP ) :: dy, d2y
936 <    real( kind = DP ) :: del, h, a, b, c, d
937 <    integer :: pp_arraySize
938 <
939 <
940 <    ! this spline code assumes that the x points are equally spaced
941 <    ! do not attempt to use this code if they are not.
942 <
943 <
944 <    ! find the closest point with a value below our own:
945 <    j = FLOOR(real((nx-1),kind=dp) * (x - xa(1)) / (xa(nx) - xa(1))) + 1
946 <
947 <    ! check to make sure we're inside the spline range:
948 <    if ((j.gt.nx).or.(j.lt.1)) then
949 <       write(errMSG,*) "EAM_splint: x is outside bounds of spline: ",x,j
950 <       call handleError(routineName,errMSG)
951 <    endif
952 <    ! check to make sure we haven't screwed up the calculation of j:
953 <    if ((x.lt.xa(j)).or.(x.gt.xa(j+1))) then
954 <       if (j.ne.nx) then
955 <          write(errMSG,*) "EAM_splint:",x," x is outside bounding range"
956 <          call handleError(routineName,errMSG)
957 <       endif
958 <    endif
959 <
960 <    del = xa(j+1) - x
961 <    h = xa(j+1) - xa(j)
962 <
963 <    a = del / h
964 <    b = 1.0E0_DP - a
965 <    c = a*(a*a - 1.0E0_DP)*h*h/6.0E0_DP
966 <    d = b*(b*b - 1.0E0_DP)*h*h/6.0E0_DP
967 <
968 <    y = a*ya(j) + b*ya(j+1) + c*yppa(j) + d*yppa(j+1)
969 <
970 <    dy = (ya(j+1)-ya(j))/h &
971 <         - (3.0E0_DP*a*a - 1.0E0_DP)*h*yppa(j)/6.0E0_DP &
972 <         + (3.0E0_DP*b*b - 1.0E0_DP)*h*yppa(j+1)/6.0E0_DP
973 <
974 <
975 <    d2y = a*yppa(j) + b*yppa(j+1)
976 <
977 <
978 <  end subroutine eam_splint
979 <
980 <
981 <  subroutine eam_spline(nx, xa, ya, yppa, yp1, ypn, boundary)
982 <
983 <
984 <    ! yp1 and ypn are the first derivatives of y at the two endpoints
985 <    ! if boundary is 'L' the lower derivative is used
986 <    ! if boundary is 'U' the upper derivative is used
987 <    ! if boundary is 'B' then both derivatives are used
988 <    ! if boundary is anything else, then both derivatives are assumed to be 0
989 <
990 <    integer :: nx, i, k, max_array_size
991 <
992 <    real( kind = DP ), dimension(:)        :: xa
993 <    real( kind = DP ), dimension(:)        :: ya
994 <    real( kind = DP ), dimension(:)        :: yppa
995 <    real( kind = DP ), dimension(size(xa)) :: u
996 <    real( kind = DP ) :: yp1,ypn,un,qn,sig,p
997 <    character(len=*) :: boundary
998 <
999 <    ! make sure the sizes match
1000 <    if ((nx /= size(xa)) .or. (nx /= size(ya))) then
1001 <       call handleWarning("EAM_SPLINE","Array size mismatch")
1002 <    end if
1003 <
1004 <    if ((boundary.eq.'l').or.(boundary.eq.'L').or. &
1005 <         (boundary.eq.'b').or.(boundary.eq.'B')) then
1006 <       yppa(1) = -0.5E0_DP
1007 <       u(1) = (3.0E0_DP/(xa(2)-xa(1)))*((ya(2)-&
1008 <            ya(1))/(xa(2)-xa(1))-yp1)
1009 <    else
1010 <       yppa(1) = 0.0E0_DP
1011 <       u(1)  = 0.0E0_DP
1012 <    endif
1013 <
1014 <    do i = 2, nx - 1
1015 <       sig = (xa(i) - xa(i-1)) / (xa(i+1) - xa(i-1))
1016 <       p = sig * yppa(i-1) + 2.0E0_DP
1017 <       yppa(i) = (sig - 1.0E0_DP) / p
1018 <       u(i) = (6.0E0_DP*((ya(i+1)-ya(i))/(xa(i+1)-xa(i)) - &
1019 <            (ya(i)-ya(i-1))/(xa(i)-xa(i-1)))/ &
1020 <            (xa(i+1)-xa(i-1)) - sig * u(i-1))/p
1021 <    enddo
1022 <
1023 <    if ((boundary.eq.'u').or.(boundary.eq.'U').or. &
1024 <         (boundary.eq.'b').or.(boundary.eq.'B')) then
1025 <       qn = 0.5E0_DP
1026 <       un = (3.0E0_DP/(xa(nx)-xa(nx-1)))* &
1027 <            (ypn-(ya(nx)-ya(nx-1))/(xa(nx)-xa(nx-1)))
1028 <    else
1029 <       qn = 0.0E0_DP
1030 <       un = 0.0E0_DP
1031 <    endif
1032 <
1033 <    yppa(nx)=(un-qn*u(nx-1))/(qn*yppa(nx-1)+1.0E0_DP)
1034 <
1035 <    do k = nx-1, 1, -1
1036 <       yppa(k)=yppa(k)*yppa(k+1)+u(k)
1037 <    enddo
1038 <
1039 <  end subroutine eam_spline
1040 <
1041 < end module eam
620 >  end subroutine do_sc_pair
621 > end module suttonchen

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines