ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/OpenMD/trunk/src/UseTheForce/DarkSide/suttonchen.F90
Revision: 938
Committed: Mon Apr 17 21:49:12 2006 UTC (19 years, 1 month ago) by gezelter
File size: 18887 byte(s)
Log Message:
Many performance improvements

File Contents

# User Rev Content
1 chuckv 842 !!
2 chuckv 702 !! Copyright (c) 2005 The University of Notre Dame. All Rights Reserved.
3     !!
4     !! The University of Notre Dame grants you ("Licensee") a
5     !! non-exclusive, royalty free, license to use, modify and
6     !! redistribute this software in source and binary code form, provided
7     !! that the following conditions are met:
8     !!
9     !! 1. Acknowledgement of the program authors must be made in any
10     !! publication of scientific results based in part on use of the
11     !! program. An acceptable form of acknowledgement is citation of
12     !! the article in which the program was described (Matthew
13     !! A. Meineke, Charles F. Vardeman II, Teng Lin, Christopher
14     !! J. Fennell and J. Daniel Gezelter, "OOPSE: An Object-Oriented
15     !! Parallel Simulation Engine for Molecular Dynamics,"
16     !! J. Comput. Chem. 26, pp. 252-271 (2005))
17     !!
18     !! 2. Redistributions of source code must retain the above copyright
19     !! notice, this list of conditions and the following disclaimer.
20     !!
21     !! 3. Redistributions in binary form must reproduce the above copyright
22     !! notice, this list of conditions and the following disclaimer in the
23     !! documentation and/or other materials provided with the
24     !! distribution.
25     !!
26     !! This software is provided "AS IS," without a warranty of any
27     !! kind. All express or implied conditions, representations and
28     !! warranties, including any implied warranty of merchantability,
29     !! fitness for a particular purpose or non-infringement, are hereby
30     !! excluded. The University of Notre Dame and its licensors shall not
31     !! be liable for any damages suffered by licensee as a result of
32     !! using, modifying or distributing the software or its
33     !! derivatives. In no event will the University of Notre Dame or its
34     !! licensors be liable for any lost revenue, profit or data, or for
35     !! direct, indirect, special, consequential, incidental or punitive
36     !! damages, however caused and regardless of the theory of liability,
37     !! arising out of the use of or inability to use software, even if the
38     !! University of Notre Dame has been advised of the possibility of
39     !! such damages.
40     !!
41    
42     !! Impliments Sutton-Chen Metallic Potential
43     !! See A.P.SUTTON and J.CHEN,PHIL MAG LETT 61,139-146,1990
44    
45    
46     module suttonchen
47     use simulation
48     use force_globals
49     use status
50     use atype_module
51     use vector_class
52 chuckv 798 use fForceOptions
53 gezelter 938 use interpolation
54 chuckv 702 #ifdef IS_MPI
55     use mpiSimulation
56     #endif
57     implicit none
58     PRIVATE
59     #define __FORTRAN90
60     #include "UseTheForce/DarkSide/fInteractionMap.h"
61    
62     INTEGER, PARAMETER :: DP = selected_real_kind(15)
63 gezelter 938 !! number of points for the spline approximations
64     INTEGER, PARAMETER :: np = 3000
65 chuckv 702
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 chuckv 728 logical, save :: haveMixingMap = .false.
71     logical, save :: useGeometricDistanceMixing = .false.
72 chuckv 835 logical, save :: cleanArrays = .true.
73     logical, save :: arraysAllocated = .false.
74 chuckv 702
75 chuckv 728
76 chuckv 702 character(len = statusMsgSize) :: errMesg
77 chuckv 714 integer :: sc_err
78 chuckv 702
79     character(len = 200) :: errMsg
80     character(len=*), parameter :: RoutineName = "Sutton-Chen MODULE"
81 gezelter 938
82 chuckv 702 type, private :: SCtype
83 gezelter 938 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 chuckv 702 end type SCtype
91 gezelter 938
92 chuckv 702
93     !! Arrays for derivatives used in force calculation
94 chuckv 713 real( kind = dp), dimension(:), allocatable :: rho
95 chuckv 702 real( kind = dp), dimension(:), allocatable :: frho
96     real( kind = dp), dimension(:), allocatable :: dfrhodrho
97 gezelter 938
98 chuckv 702 !! Arrays for MPI storage
99     #ifdef IS_MPI
100     real( kind = dp),save, dimension(:), allocatable :: dfrhodrho_col
101     real( kind = dp),save, dimension(:), allocatable :: dfrhodrho_row
102     real( kind = dp),save, dimension(:), allocatable :: frho_row
103     real( kind = dp),save, dimension(:), allocatable :: frho_col
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
107     #endif
108    
109     type, private :: SCTypeList
110     integer :: nSCTypes = 0
111 gezelter 938 integer :: currentSCtype = 0
112     type (SCtype), pointer :: SCtypes(:) => null()
113     integer, pointer :: atidToSCtype(:) => null()
114 chuckv 702 end type SCTypeList
115    
116     type (SCTypeList), save :: SCList
117    
118 gezelter 938 type:: MixParameters
119 chuckv 707 real(kind=DP) :: alpha
120     real(kind=DP) :: epsilon
121 gezelter 938 real(kind=DP) :: m
122 chuckv 728 real(Kind=DP) :: n
123 chuckv 707 real(kind=dp) :: rCut
124 gezelter 938 real(kind=dp) :: vCut
125 chuckv 707 logical :: rCutWasSet = .false.
126 gezelter 938 type(cubicSpline) :: V
127     type(cubicSpline) :: phi
128 chuckv 707 end type MixParameters
129    
130     type(MixParameters), dimension(:,:), allocatable :: MixingMap
131    
132 chuckv 702 public :: setCutoffSC
133     public :: do_SC_pair
134     public :: newSCtype
135     public :: calc_SC_prepair_rho
136 chuckv 735 public :: calc_SC_preforce_Frho
137 chuckv 702 public :: clean_SC
138     public :: destroySCtypes
139     public :: getSCCut
140 chuckv 728 ! public :: setSCDefaultCutoff
141     ! public :: setSCUniformCutoff
142 chuckv 798
143 chuckv 702
144     contains
145    
146    
147 chuckv 728 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 chuckv 702 integer :: c_ident
154     integer :: status
155 chuckv 713 integer :: nAtypes,nSCTypes,myATID
156 chuckv 702 integer :: maxVals
157     integer :: alloc_stat
158     integer :: current
159     integer,pointer :: Matchlist(:) => null()
160    
161     status = 0
162    
163    
164     !! Assume that atypes has already been set and get the total number of types in atypes
165    
166    
167     ! check to see if this is the first time into
168 chuckv 728 if (.not.associated(SCList%SCTypes)) then
169 chuckv 831 call getMatchingElementList(atypes, "is_SC", .true., nSCtypes, MatchList)
170 chuckv 728 SCList%nSCtypes = nSCtypes
171     allocate(SCList%SCTypes(nSCTypes))
172 chuckv 702 nAtypes = getSize(atypes)
173 chuckv 728 allocate(SCList%atidToSCType(nAtypes))
174 chuckv 702 end if
175    
176 chuckv 728 SCList%currentSCType = SCList%currentSCType + 1
177     current = SCList%currentSCType
178 chuckv 702
179     myATID = getFirstMatchingElement(atypes, "c_ident", c_ident)
180 chuckv 728 SCList%atidToSCType(myATID) = current
181 chuckv 702
182 chuckv 728 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 chuckv 713 end subroutine newSCtype
189 chuckv 702
190 chuckv 713
191     subroutine destroySCTypes()
192 chuckv 728 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 chuckv 926 ! Reset Capacity
201 gezelter 938 SCList%nSCTypes = 0
202 chuckv 926 SCList%currentSCtype=0
203 chuckv 702
204 chuckv 713 end subroutine destroySCTypes
205 chuckv 702
206 chuckv 713 function getSCCut(atomID) result(cutValue)
207 chuckv 702 integer, intent(in) :: atomID
208 chuckv 728 integer :: scID
209 chuckv 702 real(kind=dp) :: cutValue
210    
211 chuckv 728 scID = SCList%atidToSCType(atomID)
212 chuckv 831 cutValue = 2.0_dp * SCList%SCTypes(scID)%alpha
213 chuckv 713 end function getSCCut
214 chuckv 702
215 chuckv 713 subroutine createMixingMap()
216 gezelter 938 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 chuckv 713
221     if (SCList%currentSCtype == 0) then
222     call handleError("SuttonChen", "No members in SCMap")
223 chuckv 702 return
224     end if
225    
226 chuckv 713 nSCtypes = SCList%nSCtypes
227 chuckv 702
228 chuckv 713 if (.not. allocated(MixingMap)) then
229     allocate(MixingMap(nSCtypes, nSCtypes))
230     endif
231 chuckv 798 useGeometricDistanceMixing = usesGeometricDistanceMixing()
232 chuckv 713 do i = 1, nSCtypes
233 chuckv 702
234 chuckv 713 e1 = SCList%SCtypes(i)%epsilon
235     m1 = SCList%SCtypes(i)%m
236     n1 = SCList%SCtypes(i)%n
237     alpha1 = SCList%SCtypes(i)%alpha
238 chuckv 702
239 gezelter 938 do j = 1, nSCtypes
240 chuckv 713
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 chuckv 702
246 chuckv 728 if (useGeometricDistanceMixing) then
247 gezelter 938 alpha = sqrt(alpha1 * alpha2) !SC formulation
248 chuckv 728 else
249 gezelter 938 alpha = 0.5_dp * (alpha1 + alpha2) ! Goddard formulation
250 chuckv 728 endif
251 gezelter 938 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 chuckv 728
256 gezelter 938 dr = (rCut) / dble(np-1)
257     rvals(1) = 0.0d0
258     vvals(1) = 0.0d0
259     phivals(1) = 0.0d0
260 chuckv 842
261 gezelter 938 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     vCut = epsilon*((alpha/rCut)**n)
269    
270     call newSpline(MixingMap(i,j)%V, rvals, vvals, &
271     0.0d0, 0.0d0, .true.)
272     call newSpline(MixingMap(i,j)%phi, rvals, phivals, &
273     0.0d0, 0.0d0, .true.)
274    
275     MixingMap(i,j)%epsilon = epsilon
276     MixingMap(i,j)%m = m
277     MixingMap(i,j)%n = n
278     MixingMap(i,j)%alpha = alpha
279     MixingMap(i,j)%rCut = rcut
280     MixingMap(i,j)%vCut = vCut
281 chuckv 713 enddo
282 chuckv 702 enddo
283 chuckv 713
284     haveMixingMap = .true.
285    
286     end subroutine createMixingMap
287    
288 chuckv 702
289     !! routine checks to see if array is allocated, deallocates array if allocated
290     !! and then creates the array to the required size
291 chuckv 835 subroutine allocateSC()
292     integer :: status
293 chuckv 702
294     #ifdef IS_MPI
295     integer :: nAtomsInRow
296     integer :: nAtomsInCol
297     #endif
298     integer :: alloc_stat
299    
300 chuckv 835
301 chuckv 702 status = 0
302     #ifdef IS_MPI
303     nAtomsInRow = getNatomsInRow(plan_atom_row)
304     nAtomsInCol = getNatomsInCol(plan_atom_col)
305     #endif
306    
307     if (allocated(frho)) deallocate(frho)
308     allocate(frho(nlocal),stat=alloc_stat)
309 chuckv 713 if (alloc_stat /= 0) then
310 chuckv 702 status = -1
311     end if
312 chuckv 713
313 chuckv 702 if (allocated(rho)) deallocate(rho)
314     allocate(rho(nlocal),stat=alloc_stat)
315     if (alloc_stat /= 0) then
316     status = -1
317     end if
318    
319     if (allocated(dfrhodrho)) deallocate(dfrhodrho)
320     allocate(dfrhodrho(nlocal),stat=alloc_stat)
321     if (alloc_stat /= 0) then
322     status = -1
323     end if
324    
325     #ifdef IS_MPI
326    
327     if (allocated(rho_tmp)) deallocate(rho_tmp)
328     allocate(rho_tmp(nlocal),stat=alloc_stat)
329     if (alloc_stat /= 0) then
330     status = -1
331     end if
332    
333    
334     if (allocated(frho_row)) deallocate(frho_row)
335     allocate(frho_row(nAtomsInRow),stat=alloc_stat)
336     if (alloc_stat /= 0) then
337     status = -1
338     end if
339     if (allocated(rho_row)) deallocate(rho_row)
340     allocate(rho_row(nAtomsInRow),stat=alloc_stat)
341     if (alloc_stat /= 0) then
342     status = -1
343     end if
344     if (allocated(dfrhodrho_row)) deallocate(dfrhodrho_row)
345     allocate(dfrhodrho_row(nAtomsInRow),stat=alloc_stat)
346     if (alloc_stat /= 0) then
347     status = -1
348     end if
349    
350    
351     ! Now do column arrays
352    
353     if (allocated(frho_col)) deallocate(frho_col)
354     allocate(frho_col(nAtomsInCol),stat=alloc_stat)
355     if (alloc_stat /= 0) then
356     status = -1
357     end if
358     if (allocated(rho_col)) deallocate(rho_col)
359     allocate(rho_col(nAtomsInCol),stat=alloc_stat)
360     if (alloc_stat /= 0) then
361     status = -1
362     end if
363     if (allocated(dfrhodrho_col)) deallocate(dfrhodrho_col)
364     allocate(dfrhodrho_col(nAtomsInCol),stat=alloc_stat)
365     if (alloc_stat /= 0) then
366     status = -1
367     end if
368    
369     #endif
370 chuckv 835 if (status == -1) then
371     call handleError("SuttonChen:allocateSC","Error in allocating SC arrays")
372     end if
373     arraysAllocated = .true.
374 chuckv 713 end subroutine allocateSC
375 chuckv 702
376 gezelter 938 subroutine setCutoffSC(rcut)
377 chuckv 702 real(kind=dp) :: rcut
378 chuckv 713 SC_rcut = rcut
379     end subroutine setCutoffSC
380 gezelter 938
381     !! This array allocates module arrays if needed and builds mixing map.
382 chuckv 728 subroutine clean_SC()
383 chuckv 835 if (.not.arraysAllocated) call allocateSC()
384     if (.not.haveMixingMap) call createMixingMap()
385 chuckv 702 ! clean non-IS_MPI first
386     frho = 0.0_dp
387     rho = 0.0_dp
388     dfrhodrho = 0.0_dp
389     ! clean MPI if needed
390     #ifdef IS_MPI
391     frho_row = 0.0_dp
392     frho_col = 0.0_dp
393     rho_row = 0.0_dp
394     rho_col = 0.0_dp
395     rho_tmp = 0.0_dp
396     dfrhodrho_row = 0.0_dp
397     dfrhodrho_col = 0.0_dp
398     #endif
399 chuckv 728 end subroutine clean_SC
400 chuckv 702
401     !! Calculates rho_r
402 gezelter 938 subroutine calc_sc_prepair_rho(atom1, atom2, d, r, rijsq, rcut)
403 chuckv 702 integer :: atom1,atom2
404     real(kind = dp), dimension(3) :: d
405     real(kind = dp), intent(inout) :: r
406 gezelter 762 real(kind = dp), intent(inout) :: rijsq, rcut
407 chuckv 702 ! value of electron density rho do to atom i at atom j
408     real(kind = dp) :: rho_i_at_j
409     ! value of electron density rho do to atom j at atom i
410     real(kind = dp) :: rho_j_at_i
411    
412     ! we don't use the derivatives, dummy variables
413 chuckv 728 real( kind = dp) :: drho
414 chuckv 714 integer :: sc_err
415 chuckv 702
416     integer :: atid1,atid2 ! Global atid
417     integer :: myid_atom1 ! EAM atid
418     integer :: myid_atom2
419    
420    
421     ! check to see if we need to be cleaned at the start of a force loop
422    
423 chuckv 835 if (cleanArrays) call clean_SC()
424     cleanArrays = .false.
425 chuckv 702
426     #ifdef IS_MPI
427     Atid1 = Atid_row(Atom1)
428     Atid2 = Atid_col(Atom2)
429     #else
430     Atid1 = Atid(Atom1)
431     Atid2 = Atid(Atom2)
432     #endif
433    
434 chuckv 728 Myid_atom1 = SCList%atidtoSCtype(Atid1)
435     Myid_atom2 = SCList%atidtoSCtype(Atid2)
436 gezelter 938
437     call lookupUniformSpline(MixingMap(myid_atom1,myid_atom2)%phi, r, &
438     rho_i_at_j)
439     rho_j_at_i = rho_i_at_j
440 chuckv 702
441     #ifdef IS_MPI
442 gezelter 938 rho_col(atom2) = rho_col(atom2) + rho_i_at_j
443     rho_row(atom1) = rho_row(atom1) + rho_j_at_i
444 chuckv 702 #else
445 gezelter 938 rho(atom2) = rho(atom2) + rho_i_at_j
446     rho(atom1) = rho(atom1) + rho_j_at_i
447 chuckv 702 #endif
448 gezelter 938
449 chuckv 713 end subroutine calc_sc_prepair_rho
450 chuckv 702
451    
452 gezelter 938 !! Calculate the rho_a for all local atoms
453 chuckv 728 subroutine calc_sc_preforce_Frho(nlocal,pot)
454 chuckv 702 integer :: nlocal
455     real(kind=dp) :: pot
456     integer :: i,j
457     integer :: atom
458     integer :: atype1
459 chuckv 728 integer :: atid1
460     integer :: myid
461 chuckv 702
462 gezelter 938 !! Scatter the electron density from pre-pair calculation back to
463     !! local atoms
464 chuckv 702 #ifdef IS_MPI
465 chuckv 714 call scatter(rho_row,rho,plan_atom_row,sc_err)
466     if (sc_err /= 0 ) then
467 chuckv 702 write(errMsg,*) " Error scattering rho_row into rho"
468     call handleError(RoutineName,errMesg)
469     endif
470 chuckv 714 call scatter(rho_col,rho_tmp,plan_atom_col,sc_err)
471     if (sc_err /= 0 ) then
472 chuckv 702 write(errMsg,*) " Error scattering rho_col into rho"
473     call handleError(RoutineName,errMesg)
474 chuckv 713
475 chuckv 702 endif
476    
477     rho(1:nlocal) = rho(1:nlocal) + rho_tmp(1:nlocal)
478     #endif
479 gezelter 938
480 chuckv 713 !! Calculate F(rho) and derivative
481 chuckv 702 do atom = 1, nlocal
482 chuckv 728 Myid = SCList%atidtoSctype(Atid(atom))
483 gezelter 938 frho(atom) = - SCList%SCTypes(Myid)%c * &
484 chuckv 842 SCList%SCTypes(Myid)%epsilon * sqrt(rho(atom))
485 chuckv 728
486 chuckv 713 dfrhodrho(atom) = 0.5_dp*frho(atom)/rho(atom)
487 chuckv 842
488     pot = pot + frho(atom)
489 chuckv 702 enddo
490    
491 chuckv 731 #ifdef IS_MPI
492 chuckv 702 !! communicate f(rho) and derivatives back into row and column arrays
493 chuckv 714 call gather(frho,frho_row,plan_atom_row, sc_err)
494     if (sc_err /= 0) then
495 chuckv 702 call handleError("cal_eam_forces()","MPI gather frho_row failure")
496     endif
497 chuckv 714 call gather(dfrhodrho,dfrhodrho_row,plan_atom_row, sc_err)
498     if (sc_err /= 0) then
499 chuckv 702 call handleError("cal_eam_forces()","MPI gather dfrhodrho_row failure")
500     endif
501 chuckv 714 call gather(frho,frho_col,plan_atom_col, sc_err)
502     if (sc_err /= 0) then
503 chuckv 702 call handleError("cal_eam_forces()","MPI gather frho_col failure")
504     endif
505 chuckv 714 call gather(dfrhodrho,dfrhodrho_col,plan_atom_col, sc_err)
506     if (sc_err /= 0) then
507 chuckv 702 call handleError("cal_eam_forces()","MPI gather dfrhodrho_col failure")
508     endif
509     #endif
510 chuckv 713
511    
512 gezelter 938 end subroutine calc_sc_preforce_Frho
513    
514 chuckv 713 !! Does Sutton-Chen pairwise Force calculation.
515 gezelter 762 subroutine do_sc_pair(atom1, atom2, d, rij, r2, rcut, sw, vpair, fpair, &
516 chuckv 702 pot, f, do_pot)
517     !Arguments
518     integer, intent(in) :: atom1, atom2
519 gezelter 762 real( kind = dp ), intent(in) :: rij, r2, rcut
520 chuckv 702 real( kind = dp ) :: pot, sw, vpair
521     real( kind = dp ), dimension(3,nLocal) :: f
522     real( kind = dp ), intent(in), dimension(3) :: d
523     real( kind = dp ), intent(inout), dimension(3) :: fpair
524    
525     logical, intent(in) :: do_pot
526    
527 gezelter 938 real( kind = dp ) :: drdx, drdy, drdz
528 chuckv 728 real( kind = dp ) :: dvpdr
529 gezelter 938 real( kind = dp ) :: rhtmp, drhodr
530 chuckv 702 real( kind = dp ) :: dudr
531     real( kind = dp ) :: Fx,Fy,Fz
532 gezelter 938 real( kind = dp ) :: pot_temp, vptmp
533     real( kind = dp ) :: rcij, vcij
534     integer :: id1, id2
535 chuckv 702 integer :: mytype_atom1
536     integer :: mytype_atom2
537 gezelter 938 integer :: atid1, atid2
538 chuckv 702 !Local Variables
539 chuckv 835
540     cleanArrays = .true.
541 chuckv 702
542     #ifdef IS_MPI
543     atid1 = atid_row(atom1)
544     atid2 = atid_col(atom2)
545     #else
546     atid1 = atid(atom1)
547     atid2 = atid(atom2)
548     #endif
549    
550 chuckv 728 mytype_atom1 = SCList%atidToSCType(atid1)
551     mytype_atom2 = SCList%atidTOSCType(atid2)
552 chuckv 702
553     drdx = d(1)/rij
554     drdy = d(2)/rij
555     drdz = d(3)/rij
556 chuckv 714
557 gezelter 938 rcij = MixingMap(mytype_atom1,mytype_atom2)%rCut
558     vcij = MixingMap(mytype_atom1,mytype_atom2)%vCut
559    
560     call lookupUniformSpline1d(MixingMap(mytype_atom1, mytype_atom2)%phi, &
561     rij, rhtmp, drhodr)
562 chuckv 702
563 gezelter 938 call lookupUniformSpline1d(MixingMap(mytype_atom1, mytype_atom2)%V, &
564     rij, vptmp, dvpdr)
565 chuckv 714
566 chuckv 702 #ifdef IS_MPI
567 gezelter 938 dudr = drhodr*(dfrhodrho_row(atom1) + dfrhodrho_col(atom2)) + dvpdr
568 chuckv 702 #else
569 gezelter 938 dudr = drhodr*(dfrhodrho(atom1)+ dfrhodrho(atom2)) + dvpdr
570 chuckv 702 #endif
571 gezelter 938
572     pot_temp = vptmp - vcij
573    
574 chuckv 702 fx = dudr * drdx
575     fy = dudr * drdy
576     fz = dudr * drdz
577    
578     #ifdef IS_MPI
579     if (do_pot) then
580 chuckv 728 pot_Row(METALLIC_POT,atom1) = pot_Row(METALLIC_POT,atom1) + (pot_temp)*0.5
581     pot_Col(METALLIC_POT,atom2) = pot_Col(METALLIC_POT,atom2) + (pot_temp)*0.5
582 chuckv 702 end if
583    
584     f_Row(1,atom1) = f_Row(1,atom1) + fx
585     f_Row(2,atom1) = f_Row(2,atom1) + fy
586     f_Row(3,atom1) = f_Row(3,atom1) + fz
587    
588     f_Col(1,atom2) = f_Col(1,atom2) - fx
589     f_Col(2,atom2) = f_Col(2,atom2) - fy
590     f_Col(3,atom2) = f_Col(3,atom2) - fz
591     #else
592    
593     if(do_pot) then
594 chuckv 728 pot = pot + pot_temp
595 chuckv 702 end if
596    
597     f(1,atom1) = f(1,atom1) + fx
598     f(2,atom1) = f(2,atom1) + fy
599     f(3,atom1) = f(3,atom1) + fz
600    
601     f(1,atom2) = f(1,atom2) - fx
602     f(2,atom2) = f(2,atom2) - fy
603     f(3,atom2) = f(3,atom2) - fz
604     #endif
605    
606 chuckv 728
607 chuckv 702 #ifdef IS_MPI
608     id1 = AtomRowToGlobal(atom1)
609     id2 = AtomColToGlobal(atom2)
610     #else
611     id1 = atom1
612     id2 = atom2
613     #endif
614    
615     if (molMembershipList(id1) .ne. molMembershipList(id2)) then
616    
617     fpair(1) = fpair(1) + fx
618     fpair(2) = fpair(2) + fy
619     fpair(3) = fpair(3) + fz
620    
621     endif
622 chuckv 728 end subroutine do_sc_pair
623 chuckv 713 end module suttonchen