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 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    type (SCTypeList), save :: SCList
117  
118 <
119 <
120 <
121 < type :: MixParameters
118 >  type:: MixParameters
119       real(kind=DP) :: alpha
120       real(kind=DP) :: epsilon
121 <     real(kind=dp) :: sigma6
121 >     real(kind=DP) :: m
122 >     real(Kind=DP) :: n
123       real(kind=dp) :: rCut
124 <     real(kind=dp) :: delta
124 >     real(kind=dp) :: vCut
125       logical       :: rCutWasSet = .false.
126 <     logical       :: shiftedPot
127 <     logical       :: isSoftCore = .false.
126 >     type(cubicSpline) :: V
127 >     type(cubicSpline) :: phi
128    end type MixParameters
129  
130    type(MixParameters), dimension(:,:), allocatable :: MixingMap
131  
134
135
136  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 newSCtype(c,m,n,alpha,epsilon,c_ident,status)
148 <    real (kind = dp )                      :: lattice_constant
149 <    integer                                :: eam_nrho
150 <    real (kind = dp )                      :: eam_drho
151 <    integer                                :: eam_nr
152 <    real (kind = dp )                      :: eam_dr
154 <    real (kind = dp )                      :: rcut
155 <    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
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 <
161 <    integer                                :: nAtypes,nEAMTypes,myATID
155 >    integer                                :: nAtypes,nSCTypes,myATID
156      integer                                :: maxVals
157      integer                                :: alloc_stat
158      integer                                :: current
# Line 168 | Line 162 | contains
162  
163  
164      !! 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.
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
188 <
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
194 <
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
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
206 <
207 <  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
211 <  subroutine destroyEAMtypes()
212 <    integer :: i
213 <    type(EAMType), pointer :: tempEAMType=>null()
204 >  end subroutine destroySCTypes
205  
206 <    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()
221 <
222 <    eamList%n_eam_types = 0
223 <    eamList%currentAddition = 0
224 <
225 <  end subroutine destroyEAMtypes
226 <
227 <  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
241 <    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
245 <    if (EAMList%currentAddition == 0) then
246 <       call handleError("init_EAM_FF","No members in EAMList")
247 <       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
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
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, &
284 <            EAMList%EAMParams(i)%eam_rho_r, &
285 <            EAMList%EAMParams(i)%eam_rho_r_pp, &
286 <            0.0E0_DP, 0.0E0_DP, 'N')
287 <       call eam_spline(number_r, EAMList%EAMParams(i)%eam_rvals, &
288 <            EAMList%EAMParams(i)%eam_Z_r, &
289 <            EAMList%EAMParams(i)%eam_Z_r_pp, &
290 <            0.0E0_DP, 0.0E0_DP, 'N')
291 <       call eam_spline(number_rho, EAMList%EAMParams(i)%eam_rhovals, &
292 <            EAMList%EAMParams(i)%eam_F_rho, &
293 <            EAMList%EAMParams(i)%eam_F_rho_pp, &
294 <            0.0E0_DP, 0.0E0_DP, 'N')
295 <       call eam_spline(number_r, EAMList%EAMParams(i)%eam_rvals, &
296 <            EAMList%EAMParams(i)%eam_phi_r, &
297 <            EAMList%EAMParams(i)%eam_phi_r_pp, &
298 <            0.0E0_DP, 0.0E0_DP, 'N')
299 <    enddo
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
303 <    !       do i = 2, EAMList%currentAddition
304 <    !          current_rcut_max =max(current_rcut_max,EAMList%EAMParams(i)%eam_rcut)
305 <    !       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  
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
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 331 | 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 340 | 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
345       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
351       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
358       return
321      end if
322  
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
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
374       return
329      end if
330  
331  
# Line 379 | Line 333 | contains
333      allocate(frho_row(nAtomsInRow),stat=alloc_stat)
334      if (alloc_stat /= 0) then
335         status = -1
382       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
388       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
394       return
346      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
347  
348  
349      ! Now do column arrays
# Line 407 | Line 352 | contains
352      allocate(frho_col(nAtomsInCol),stat=alloc_stat)
353      if (alloc_stat /= 0) then
354         status = -1
410       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
416       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
422       return
365      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
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
434 <
435 <  !! C sets rcut to be the largest cutoff of any atype
436 <  !! present in this simulation. Doesn't include all atypes
437 <  !! sim knows about, just those in the simulation.
438 <  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 <
447 <
448 <
449 <  subroutine clean_EAM()
450 <
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 462 | 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  
467
468
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
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 571 | 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  
575
576
424   #ifdef IS_MPI
425      Atid1 = Atid_row(Atom1)
426      Atid2 = Atid_col(Atom2)
# Line 582 | 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  
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)
597
598
599
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  
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)
449  
450 <
451 <
617 <
618 < #ifdef  IS_MPI
619 <       rho_row(atom1) = rho_row(atom1) + rho_j_at_i
620 < #else
621 <       rho(atom1) = rho(atom1) + rho_j_at_i
622 < #endif
623 <    endif
624 <
625 <
626 <
627 <
628 <
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)
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
641    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.
648 <    !! 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 <
665 <
666 <    !! 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
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
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
691 <       dfrhodrho(atom) = u1
692 <       d2frhodrhodrho(atom) = u2
693 <       pot = pot + u
694 <
486 >       pot = pot + frho(atom)
487      enddo
488  
697
698
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
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
507   #endif
508 <
509 <
510 <  end subroutine calc_eam_preforce_Frho
511 <
512 <
513 <
733 <
734 <  !! Does EAM pairwise Force calculation.  
735 <  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 744 | 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
750 <    real( kind = dp ) :: rha,drha,d2rha, dpha
751 <    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
753    real( kind = dp ) :: rci,rcj
754    real( kind = dp ) :: drhoidr,drhojdr
755    real( kind = dp ) :: d2rhoidrdr
756    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  
766    ! write(*,*) "Frho: ", Frho(atom1)
767
768    phab = 0.0E0_DP
769    dvpdr = 0.0E0_DP
770    d2vpdrdr = 0.0E0_DP
771
772    if (rij .lt. EAM_rcut) then
773
540   #ifdef IS_MPI
541         atid1 = atid_row(atom1)
542         atid2 = atid_col(atom2)
# Line 779 | 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  
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
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, &
800 <               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
808 <
809 <       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)
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, &
820 <               EAMList%EAMParams(mytype_atom2)%eam_phi_r, &
821 <               EAMList%EAMParams(mytype_atom2)%eam_phi_r_pp, &
822 <               rij, phb,dphb,d2phb)
823 <       endif
824 <
825 <       if (rij.lt.rci) then
826 <          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
834 <
835 <       if (rij.lt.rcj) then
836 <          phab = phab + 0.5E0_DP*(rha/rhb)*phb
837 <          dvpdr = dvpdr + 0.5E0_DP*((rha/rhb)*dphb + &
838 <               phb*((drha/rhb) - (rha*drhb/rhb/rhb)))
839 <          d2vpdrdr = d2vpdrdr + 0.5E0_DP*((rha/rhb)*d2phb + &
840 <               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
844 <
845 <       drhoidr = drha
846 <       drhojdr = drhb
847 <
848 <       d2rhoidrdr = d2rha
849 <       d2rhojdrdr = d2rhb
850 <
851 <
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) &
854 <            + dvpdr
855 <
565 >       dudr = drhodr*(dfrhodrho_row(atom1) + dfrhodrho_col(atom2)) + dvpdr
566   #else
567 <       dudr = drhojdr*dfrhodrho(atom1)+drhoidr*dfrhodrho(atom2) &
858 <            + dvpdr
859 <       ! 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  
866
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 880 | 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 892 | 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 908 | Line 617 | contains
617            fpair(3) = fpair(3) + fz
618  
619         endif
620 <
621 <       if (nmflag) then
913 <
914 <          drhoidr = drha
915 <          drhojdr = drhb
916 <          d2rhoidrdr = d2rha
917 <          d2rhojdrdr = d2rhb
918 <
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)
925 <
926 < #else
927 <
928 <          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
620 >  end subroutine do_sc_pair
621 > end module suttonchen

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines