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 2434 by chuckv, Tue Nov 15 16:18:36 2005 UTC vs.
Revision 2722 by gezelter, Thu Apr 20 18:24:24 2006 UTC

# Line 49 | Line 49 | module suttonchen
49    use status
50    use atype_module
51    use vector_class
52 +  use fForceOptions
53 +  use interpolation
54   #ifdef IS_MPI
55    use mpiSimulation
56   #endif
# Line 58 | Line 60 | module suttonchen
60   #include "UseTheForce/DarkSide/fInteractionMap.h"
61  
62    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
# Line 65 | Line 69 | module suttonchen
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  
70
71
76    character(len = statusMsgSize) :: errMesg
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
78 <  logical :: cleanme = .true.
79 <  logical :: nmflag  = .false.
80 <
81 <
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
89 <     real(kind=dp)     :: sc_rcut
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  
92
93    !! Arrays for derivatives used in force calculation
94    real( kind = dp), dimension(:), allocatable :: rho
95    real( kind = dp), dimension(:), allocatable :: frho
96    real( kind = dp), dimension(:), allocatable :: dfrhodrho
97 <
98 <
99 <
97 >  
98    !! Arrays for MPI storage
99   #ifdef IS_MPI
100    real( kind = dp),save, dimension(:), allocatable :: dfrhodrho_col
# Line 110 | Line 108 | module suttonchen
108  
109    type, private :: SCTypeList
110       integer           :: nSCTypes = 0
111 <     integer           :: currentSCtype = 0
112 <
113 <     type (SCtype), pointer  :: SCtypes(:) => null()
116 <     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 <
122 <
123 <
124 < type :: MixParameters
118 >  type:: MixParameters
119       real(kind=DP) :: alpha
120       real(kind=DP) :: epsilon
121 <     real(kind=DP) :: m
121 >     real(kind=DP) :: m
122       real(Kind=DP) :: n
129     real(kind=DP) :: vpair_pot
123       real(kind=dp) :: rCut
124 +     real(kind=dp) :: vCut
125       logical       :: rCutWasSet = .false.
126 <
126 >     type(cubicSpline) :: V
127 >     type(cubicSpline) :: phi
128    end type MixParameters
129  
130    type(MixParameters), dimension(:,:), allocatable :: MixingMap
131  
137
138
132    public :: setCutoffSC
133    public :: do_SC_pair
134    public :: newSCtype
# Line 146 | Line 139 | module suttonchen
139    public :: getSCCut
140   ! public :: setSCDefaultCutoff
141   ! public :: setSCUniformCutoff
142 <  public :: useGeometricMixing
142 >
143  
144   contains
145  
# Line 157 | Line 150 | contains
150      real (kind = dp )                      :: n ! Pair Potential Exponent
151      real (kind = dp )                      :: alpha ! Length Scaling
152      real (kind = dp )                      :: epsilon ! Energy Scaling
160
161
153      integer                                :: c_ident
154      integer                                :: status
164
155      integer                                :: nAtypes,nSCTypes,myATID
156      integer                                :: maxVals
157      integer                                :: alloc_stat
# Line 176 | Line 166 | contains
166  
167      ! check to see if this is the first time into
168      if (.not.associated(SCList%SCTypes)) then
169 <       call getMatchingElementList(atypes, "is_SuttonChen", .true., nSCtypes, MatchList)
169 >       call getMatchingElementList(atypes, "is_SC", .true., nSCtypes, MatchList)
170         SCList%nSCtypes = nSCtypes
171         allocate(SCList%SCTypes(nSCTypes))
172         nAtypes = getSize(atypes)
# Line 188 | Line 178 | contains
178  
179      myATID =  getFirstMatchingElement(atypes, "c_ident", c_ident)
180      SCList%atidToSCType(myATID) = current
191
192
181    
182      SCList%SCTypes(current)%atid         = c_ident
183      SCList%SCTypes(current)%alpha        = alpha
# Line 209 | Line 197 | contains
197         deallocate(SCList%atidToSCtype)
198         SCList%atidToSCtype=>null()
199      end if
200 + ! Reset Capacity
201 +    SCList%nSCTypes = 0
202 +    SCList%currentSCtype=0
203  
213
204    end subroutine destroySCTypes
205  
216
217
206    function getSCCut(atomID) result(cutValue)
207      integer, intent(in) :: atomID
208      integer :: scID
209      real(kind=dp) :: cutValue
210      
211      scID = SCList%atidToSCType(atomID)
212 <    cutValue = SCList%SCTypes(scID)%sc_rcut
212 >    cutValue = 2.0_dp * SCList%SCTypes(scID)%alpha
213    end function getSCCut
214  
227
228
229
215    subroutine createMixingMap()
216 <    integer :: nSCtypes, i, j
217 <    real ( kind = dp ) :: e1, e2,m1,m2,alpha1,alpha2,n1,n2
218 <    real ( kind = dp ) :: rcut6, tp6, tp12
219 <    logical :: isSoftCore1, isSoftCore2, doShift
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      if (SCList%currentSCtype == 0) then
222         call handleError("SuttonChen", "No members in SCMap")
# Line 243 | Line 228 | contains
228      if (.not. allocated(MixingMap)) then
229         allocate(MixingMap(nSCtypes, nSCtypes))
230      endif
231 <
231 >    useGeometricDistanceMixing = usesGeometricDistanceMixing()
232      do i = 1, nSCtypes
233  
234         e1 = SCList%SCtypes(i)%epsilon
# Line 251 | Line 236 | contains
236         n1 = SCList%SCtypes(i)%n
237         alpha1 = SCList%SCtypes(i)%alpha
238  
239 <       do j = i, nSCtypes
239 >       do j = 1, nSCtypes
240            
256
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            if (useGeometricDistanceMixing) then
247 <             MixingMap(i,j)%alpha = sqrt(alpha1 * alpha2) !SC formulation
247 >             alpha = sqrt(alpha1 * alpha2) !SC formulation
248            else
249 <             MixingMap(i,j)%alpha = 0.5_dp * (alpha1 + alpha2) ! Goddard formulation
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 <          MixingMap(i,j)%epsilon = sqrt(e1 * e2)
257 <          MixingMap(i,j)%m = 0.5_dp*(m1+m2)
258 <          MixingMap(i,j)%n = 0.5_dp*(n1+n2)
259 <          MixingMap(i,j)%alpha = 0.5_dp*(alpha1+alpha2)
260 <          MixingMap(i,j)%rcut = 2.0_dp *MixingMap(i,j)%alpha
261 <          MixingMap(i,j)%vpair_pot = MixingMap(i,j)%epsilon* &
262 <               (MixingMap(i,j)%alpha/MixingMap(i,j)%rcut)**MixingMap(i,j)%n
263 <          if (i.ne.j) then
264 <             MixingMap(j,i)%epsilon    = MixingMap(i,j)%epsilon
265 <             MixingMap(j,i)%m          = MixingMap(i,j)%m
266 <             MixingMap(j,i)%n          = MixingMap(i,j)%n
267 <             MixingMap(j,i)%alpha      = MixingMap(i,j)%alpha
268 <             MixingMap(j,i)%rcut = MixingMap(i,j)%rcut
269 <             MixingMap(j,i)%vpair_pot = MixingMap(i,j)%vpair_pot
270 <          endif
256 >          dr = (rCut) / dble(np-1)
257 >          rvals(1) = 0.0d0
258 >          vvals(1) = 0.0d0
259 >          phivals(1) = 0.0d0
260 >
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 >          vCut = epsilon*((alpha/rCut)**n)
269 >
270 >          call newSpline(MixingMap(i,j)%V, rvals, vvals, .true.)
271 >          call newSpline(MixingMap(i,j)%phi, rvals, phivals, .true.)
272 >
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      
# Line 290 | Line 286 | contains
286  
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 allocateSC(status)
290 <    integer, intent(out) :: status
289 >  subroutine allocateSC()
290 >    integer :: status
291  
292   #ifdef IS_MPI
293      integer :: nAtomsInRow
# Line 299 | 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)
302      nAtomsInCol = getNatomsInCol(plan_atom_col)
303   #endif
304  
309
310
305      if (allocated(frho)) deallocate(frho)
306      allocate(frho(nlocal),stat=alloc_stat)
307      if (alloc_stat /= 0) then
308         status = -1
315       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
322       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
329       return
321      end if
322  
323   #ifdef IS_MPI
# Line 335 | Line 326 | contains
326      allocate(rho_tmp(nlocal),stat=alloc_stat)
327      if (alloc_stat /= 0) then
328         status = -1
338       return
329      end if
330  
331  
# Line 343 | Line 333 | contains
333      allocate(frho_row(nAtomsInRow),stat=alloc_stat)
334      if (alloc_stat /= 0) then
335         status = -1
346       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
352       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
358       return
346      end if
347  
348  
# Line 365 | Line 352 | contains
352      allocate(frho_col(nAtomsInCol),stat=alloc_stat)
353      if (alloc_stat /= 0) then
354         status = -1
368       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
374       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
380       return
365      end if
366  
367   #endif
368 <
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 <  !! C sets rcut to be the largest cutoff of any atype
388 <  !! present in this simulation. Doesn't include all atypes
389 <  !! sim knows about, just those in the simulation.
390 <  subroutine setCutoffSC(rcut, status)
374 >  subroutine setCutoffSC(rcut)
375      real(kind=dp) :: rcut
392    integer :: status
393    status = 0
394
376      SC_rcut = rcut
396
377    end subroutine setCutoffSC
378 <
379 <  subroutine useGeometricMixing()
400 <    useGeometricDistanceMixing = .true.
401 <    haveMixingMap = .false.
402 <    return
403 <  end subroutine useGeometricMixing
404 <  
405 <
406 <
407 <
408 <
409 <
410 <
411 <
412 <
378 >  
379 >  !! This array allocates module arrays if needed and builds mixing map.
380    subroutine clean_SC()
381 <
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 428 | Line 396 | contains
396   #endif
397    end subroutine clean_SC
398  
431
432
399    !! Calculates rho_r
400 <  subroutine calc_sc_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
# Line 452 | 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  
456
457
424   #ifdef IS_MPI
425      Atid1 = Atid_row(Atom1)
426      Atid2 = Atid_col(Atom2)
# Line 465 | Line 431 | contains
431  
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  
469
470
471       rho_i_at_j = (MixingMap(Myid_atom1,Myid_atom2)%alpha/r)&
472            **MixingMap(Myid_atom1,Myid_atom2)%m
473       rho_j_at_i = rho_i_at_j
474
439   #ifdef  IS_MPI
440 <       rho_col(atom2) = rho_col(atom2) + rho_i_at_j
441 <       rho_row(atom1) = rho_row(atom1) + rho_j_at_i
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
444 <       rho(atom1) = rho(atom1) + rho_j_at_i
443 >    rho(atom2) = rho(atom2) + rho_i_at_j
444 >    rho(atom1) = rho(atom1) + rho_j_at_i
445   #endif
446 <
446 >    
447    end subroutine calc_sc_prepair_rho
448  
449  
450 < !! Calculate the rho_a for all local atoms
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
492    real(kind=dp) :: U,U1,U2
456      integer :: atype1
457      integer :: atid1
458      integer :: myid
459  
460 <
461 <    cleanme = .true.
499 <    !! 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,sc_err)
464      if (sc_err /= 0 ) then
# Line 512 | Line 474 | contains
474  
475      rho(1:nlocal) = rho(1:nlocal) + rho_tmp(1:nlocal)
476   #endif
477 <
516 <
517 <
477 >    
478      !! Calculate F(rho) and derivative
479      do atom = 1, nlocal
480         Myid = SCList%atidtoSctype(Atid(atom))
481 <       frho(atom) = -SCList%SCTypes(Myid)%c * &
482 <            SCList%SCTypes(Myid)%epsilon * sqrt(rho(i))
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 <       pot = pot + u
485 >
486 >       pot = pot + frho(atom)
487      enddo
488  
489   #ifdef IS_MPI
# Line 546 | Line 507 | contains
507   #endif
508      
509      
510 <  end subroutine calc_sc_preforce_Frho
511 <
551 <
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, sw, vpair, fpair, &
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 562 | Line 522 | contains
522  
523      logical, intent(in) :: do_pot
524  
525 <    real( kind = dp ) :: drdx,drdy,drdz
525 >    real( kind = dp ) :: drdx, drdy, drdz
526      real( kind = dp ) :: dvpdr
527 <    real( kind = dp ) :: drhodr
527 >    real( kind = dp ) :: rhtmp, drhodr
528      real( kind = dp ) :: dudr
569    real( kind = dp ) :: rcij
570    real( kind = dp ) :: drhoidr,drhojdr
529      real( kind = dp ) :: Fx,Fy,Fz
530 <    real( kind = dp ) :: r,d2pha,phb,d2phb
531 <    real( kind = dp ) :: pot_temp,vptmp
532 <    real( kind = dp ) :: epsilonij,aij,nij,mij,vcij
575 <    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  
581    ! write(*,*) "Frho: ", Frho(atom1)
582
583
584    dvpdr = 0.0E0_DP
585
586
540   #ifdef IS_MPI
541         atid1 = atid_row(atom1)
542         atid2 = atid_col(atom2)
# Line 598 | Line 551 | contains
551         drdx = d(1)/rij
552         drdy = d(2)/rij
553         drdz = d(3)/rij
601
554                  
555 <       epsilonij = MixingMap(mytype_atom1,mytype_atom2)%epsilon
556 <       aij       = MixingMap(mytype_atom1,mytype_atom2)%alpha
605 <       nij       = MixingMap(mytype_atom1,mytype_atom2)%n
606 <       mij       = MixingMap(mytype_atom1,mytype_atom2)%m
607 <       vcij      = MixingMap(mytype_atom1,mytype_atom2)%vpair_pot              
608 <
609 <       vptmp = epsilonij*((aij/r)**nij)
610 <
611 <
612 <       dvpdr = -nij*vptmp/r
613 <       drhodr = -mij*((aij/r)**mij)/r
614 <
555 >       rcij = MixingMap(mytype_atom1,mytype_atom2)%rCut
556 >       vcij = MixingMap(mytype_atom1,mytype_atom2)%vCut
557        
558 <       dudr = drhodr*(dfrhodrho(atom1)+dfrhodrho(atom2)) &
559 <            + dvpdr
618 <      
619 <       pot_temp = vptmp + vcij
620 <
558 >       call lookupUniformSpline1d(MixingMap(mytype_atom1, mytype_atom2)%phi, &
559 >            rij, rhtmp, drhodr)
560  
561 +       call lookupUniformSpline1d(MixingMap(mytype_atom1, mytype_atom2)%V, &
562 +            rij, vptmp, dvpdr)
563 +      
564   #ifdef IS_MPI
565 <       dudr = drhodr*(dfrhodrho_row(atom1)+dfrhodrho_col(atom2)) &
624 <            + dvpdr
625 <
565 >       dudr = drhodr*(dfrhodrho_row(atom1) + dfrhodrho_col(atom2)) + dvpdr
566   #else
567 <       dudr = drhodr*(dfrhodrho(atom1)+dfrhodrho(atom2)) &
628 <            + dvpdr
567 >       dudr = drhodr*(dfrhodrho(atom1)+ dfrhodrho(atom2)) + dvpdr
568   #endif
569 <
570 <
569 >              
570 >       pot_temp = vptmp - vcij
571 >
572         fx = dudr * drdx
573         fy = dudr * drdy
574         fz = dudr * drdz
575  
636
576   #ifdef IS_MPI
577         if (do_pot) then
578            pot_Row(METALLIC_POT,atom1) = pot_Row(METALLIC_POT,atom1) + (pot_temp)*0.5
# Line 678 | Line 617 | contains
617            fpair(3) = fpair(3) + fz
618  
619         endif
681
682
620    end subroutine do_sc_pair
684
685
686
621   end module suttonchen

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines