ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE-4/src/UseTheForce/doForces.F90
(Generate patch)

Comparing trunk/OOPSE-4/src/UseTheForce/doForces.F90 (file contents):
Revision 2301 by gezelter, Thu Sep 15 22:05:21 2005 UTC vs.
Revision 2407 by chrisfen, Wed Nov 2 20:35:34 2005 UTC

# Line 45 | Line 45
45  
46   !! @author Charles F. Vardeman II
47   !! @author Matthew Meineke
48 < !! @version $Id: doForces.F90,v 1.44 2005-09-15 22:05:17 gezelter Exp $, $Date: 2005-09-15 22:05:17 $, $Name: not supported by cvs2svn $, $Revision: 1.44 $
48 > !! @version $Id: doForces.F90,v 1.66 2005-11-02 20:35:34 chrisfen Exp $, $Date: 2005-11-02 20:35:34 $, $Name: not supported by cvs2svn $, $Revision: 1.66 $
49  
50  
51   module doForces
# Line 58 | Line 58 | module doForces
58    use lj
59    use sticky
60    use electrostatic_module
61 <  use reaction_field_module
62 <  use gb_pair
61 >  use gayberne
62    use shapes
63    use vector_class
64    use eam
# Line 75 | Line 74 | module doForces
74   #include "UseTheForce/fSwitchingFunction.h"
75   #include "UseTheForce/fCutoffPolicy.h"
76   #include "UseTheForce/DarkSide/fInteractionMap.h"
77 + #include "UseTheForce/DarkSide/fElectrostaticSummationMethod.h"
78  
79  
80    INTEGER, PARAMETER:: PREPAIR_LOOP = 1
# Line 85 | Line 85 | module doForces
85    logical, save :: haveSaneForceField = .false.
86    logical, save :: haveInteractionHash = .false.
87    logical, save :: haveGtypeCutoffMap = .false.
88 +  logical, save :: haveDefaultCutoffs = .false.
89    logical, save :: haveRlist = .false.
90  
91    logical, save :: FF_uses_DirectionalAtoms
92    logical, save :: FF_uses_Dipoles
93    logical, save :: FF_uses_GayBerne
94    logical, save :: FF_uses_EAM
94  logical, save :: FF_uses_RF
95  
96    logical, save :: SIM_uses_DirectionalAtoms
97    logical, save :: SIM_uses_EAM
98  logical, save :: SIM_uses_RF
98    logical, save :: SIM_requires_postpair_calc
99    logical, save :: SIM_requires_prepair_calc
100    logical, save :: SIM_uses_PBC
101  
102 <  integer, save :: corrMethod
102 >  integer, save :: electrostaticSummationMethod
103  
104    public :: init_FF
105    public :: setDefaultCutoffs
# Line 124 | Line 123 | module doForces
123    ! Bit hash to determine pair-pair interactions.
124    integer, dimension(:,:), allocatable :: InteractionHash
125    real(kind=dp), dimension(:), allocatable :: atypeMaxCutoff
126 <  real(kind=dp), dimension(:), allocatable :: groupMaxCutoff
127 <  integer, dimension(:), allocatable :: groupToGtype
128 <  real(kind=dp), dimension(:), allocatable :: gtypeMaxCutoff
126 >  real(kind=dp), dimension(:), allocatable, target :: groupMaxCutoffRow
127 >  real(kind=dp), dimension(:), pointer :: groupMaxCutoffCol
128 >
129 >  integer, dimension(:), allocatable, target :: groupToGtypeRow
130 >  integer, dimension(:), pointer :: groupToGtypeCol => null()
131 >
132 >  real(kind=dp), dimension(:), allocatable,target :: gtypeMaxCutoffRow
133 >  real(kind=dp), dimension(:), pointer :: gtypeMaxCutoffCol
134    type ::gtypeCutoffs
135       real(kind=dp) :: rcut
136       real(kind=dp) :: rcutsq
# Line 136 | Line 140 | module doForces
140  
141    integer, save :: cutoffPolicy = TRADITIONAL_CUTOFF_POLICY
142    real(kind=dp),save :: defaultRcut, defaultRsw, defaultRlist
143 <  real(kind=dp),save :: rcuti
143 >  real(kind=dp),save :: listSkin
144    
145   contains
146  
# Line 180 | Line 184 | contains
184  
185      if (.not. allocated(InteractionHash)) then
186         allocate(InteractionHash(nAtypes,nAtypes))
187 +    else
188 +       deallocate(InteractionHash)
189 +       allocate(InteractionHash(nAtypes,nAtypes))
190      endif
191  
192      if (.not. allocated(atypeMaxCutoff)) then
193         allocate(atypeMaxCutoff(nAtypes))
194 +    else
195 +       deallocate(atypeMaxCutoff)
196 +       allocate(atypeMaxCutoff(nAtypes))
197      endif
198          
199      do i = 1, nAtypes
# Line 260 | Line 270 | contains
270      logical :: GtypeFound
271  
272      integer :: myStatus, nAtypes,  i, j, istart, iend, jstart, jend
273 <    integer :: n_in_i, me_i, ia, g, atom1, nGroupTypes
273 >    integer :: n_in_i, me_i, ia, g, atom1, ja, n_in_j,me_j
274      integer :: nGroupsInRow
275 <    real(kind=dp):: thisSigma, bigSigma, thisRcut, tol, skin
275 >    integer :: nGroupsInCol
276 >    integer :: nGroupTypesRow,nGroupTypesCol
277 >    real(kind=dp):: thisSigma, bigSigma, thisRcut, tradRcut, tol, skin
278      real(kind=dp) :: biggestAtypeCutoff
279  
280      stat = 0
# Line 276 | Line 288 | contains
288      endif
289   #ifdef IS_MPI
290      nGroupsInRow = getNgroupsInRow(plan_group_row)
291 +    nGroupsInCol = getNgroupsInCol(plan_group_col)
292   #endif
293      nAtypes = getSize(atypes)
294   ! Set all of the initial cutoffs to zero.
# Line 291 | Line 304 | contains
304            call getElementProperty(atypes, i, "is_Shape", i_is_Shape)
305            
306  
307 <          if (i_is_LJ) then
308 <             thisRcut = getSigma(i) * 2.5_dp
309 <             if (thisRCut .gt. atypeMaxCutoff(i)) atypeMaxCutoff(i) = thisRCut
310 <          endif
311 <          if (i_is_Elect) then
312 <             thisRcut = defaultRcut
313 <             if (thisRCut .gt. atypeMaxCutoff(i)) atypeMaxCutoff(i) = thisRCut
314 <          endif
315 <          if (i_is_Sticky) then
316 <             thisRcut = getStickyCut(i)
317 <             if (thisRCut .gt. atypeMaxCutoff(i)) atypeMaxCutoff(i) = thisRCut
307 >          if (haveDefaultCutoffs) then
308 >             atypeMaxCutoff(i) = defaultRcut
309 >          else
310 >             if (i_is_LJ) then          
311 >                thisRcut = getSigma(i) * 2.5_dp
312 >                if (thisRCut .gt. atypeMaxCutoff(i)) atypeMaxCutoff(i) = thisRCut
313 >             endif
314 >             if (i_is_Elect) then
315 >                thisRcut = defaultRcut
316 >                if (thisRCut .gt. atypeMaxCutoff(i)) atypeMaxCutoff(i) = thisRCut
317 >             endif
318 >             if (i_is_Sticky) then
319 >                thisRcut = getStickyCut(i)
320 >                if (thisRCut .gt. atypeMaxCutoff(i)) atypeMaxCutoff(i) = thisRCut
321 >             endif
322 >             if (i_is_StickyP) then
323 >                thisRcut = getStickyPowerCut(i)
324 >                if (thisRCut .gt. atypeMaxCutoff(i)) atypeMaxCutoff(i) = thisRCut
325 >             endif
326 >             if (i_is_GB) then
327 >                thisRcut = getGayBerneCut(i)
328 >                if (thisRCut .gt. atypeMaxCutoff(i)) atypeMaxCutoff(i) = thisRCut
329 >             endif
330 >             if (i_is_EAM) then
331 >                thisRcut = getEAMCut(i)
332 >                if (thisRCut .gt. atypeMaxCutoff(i)) atypeMaxCutoff(i) = thisRCut
333 >             endif
334 >             if (i_is_Shape) then
335 >                thisRcut = getShapeCut(i)
336 >                if (thisRCut .gt. atypeMaxCutoff(i)) atypeMaxCutoff(i) = thisRCut
337 >             endif
338            endif
306          if (i_is_StickyP) then
307             thisRcut = getStickyPowerCut(i)
308             if (thisRCut .gt. atypeMaxCutoff(i)) atypeMaxCutoff(i) = thisRCut
309          endif
310          if (i_is_GB) then
311             thisRcut = getGayBerneCut(i)
312             if (thisRCut .gt. atypeMaxCutoff(i)) atypeMaxCutoff(i) = thisRCut
313          endif
314          if (i_is_EAM) then
315             thisRcut = getEAMCut(i)
316             if (thisRCut .gt. atypeMaxCutoff(i)) atypeMaxCutoff(i) = thisRCut
317          endif
318          if (i_is_Shape) then
319             thisRcut = getShapeCut(i)
320             if (thisRCut .gt. atypeMaxCutoff(i)) atypeMaxCutoff(i) = thisRCut
321          endif
339            
340 +          
341            if (atypeMaxCutoff(i).gt.biggestAtypeCutoff) then
342               biggestAtypeCutoff = atypeMaxCutoff(i)
343            endif
344 +
345         endif
346      enddo
347    
348 <    nGroupTypes = 0
348 >
349      
350      istart = 1
351 +    jstart = 1
352   #ifdef IS_MPI
353      iend = nGroupsInRow
354 +    jend = nGroupsInCol
355   #else
356      iend = nGroups
357 +    jend = nGroups
358   #endif
359      
360      !! allocate the groupToGtype and gtypeMaxCutoff here.
361 <    if(.not.allocated(groupToGtype)) then
362 <       allocate(groupToGtype(iend))
363 <       allocate(groupMaxCutoff(iend))
364 <       allocate(gtypeMaxCutoff(iend))
365 <       groupMaxCutoff = 0.0_dp
366 <       gtypeMaxCutoff = 0.0_dp
361 >    if(.not.allocated(groupToGtypeRow)) then
362 >     !  allocate(groupToGtype(iend))
363 >       allocate(groupToGtypeRow(iend))
364 >    else
365 >       deallocate(groupToGtypeRow)
366 >       allocate(groupToGtypeRow(iend))
367      endif
368 +    if(.not.allocated(groupMaxCutoffRow)) then
369 +       allocate(groupMaxCutoffRow(iend))
370 +    else
371 +       deallocate(groupMaxCutoffRow)
372 +       allocate(groupMaxCutoffRow(iend))
373 +    end if
374 +
375 +    if(.not.allocated(gtypeMaxCutoffRow)) then
376 +       allocate(gtypeMaxCutoffRow(iend))
377 +    else
378 +       deallocate(gtypeMaxCutoffRow)
379 +       allocate(gtypeMaxCutoffRow(iend))
380 +    endif
381 +
382 +
383 + #ifdef IS_MPI
384 +       ! We only allocate new storage if we are in MPI because Ncol /= Nrow
385 +    if(.not.associated(groupToGtypeCol)) then
386 +       allocate(groupToGtypeCol(jend))
387 +    else
388 +       deallocate(groupToGtypeCol)
389 +       allocate(groupToGtypeCol(jend))
390 +    end if
391 +
392 +    if(.not.associated(groupToGtypeCol)) then
393 +       allocate(groupToGtypeCol(jend))
394 +    else
395 +       deallocate(groupToGtypeCol)
396 +       allocate(groupToGtypeCol(jend))
397 +    end if
398 +    if(.not.associated(gtypeMaxCutoffCol)) then
399 +       allocate(gtypeMaxCutoffCol(jend))
400 +    else
401 +       deallocate(gtypeMaxCutoffCol)      
402 +       allocate(gtypeMaxCutoffCol(jend))
403 +    end if
404 +
405 +       groupMaxCutoffCol = 0.0_dp
406 +       gtypeMaxCutoffCol = 0.0_dp
407 +
408 + #endif
409 +       groupMaxCutoffRow = 0.0_dp
410 +       gtypeMaxCutoffRow = 0.0_dp
411 +
412 +
413      !! first we do a single loop over the cutoff groups to find the
414      !! largest cutoff for any atypes present in this group.  We also
415      !! create gtypes at this point.
416      
417      tol = 1.0d-6
418 <    
418 >    nGroupTypesRow = 0
419 >
420      do i = istart, iend      
421         n_in_i = groupStartRow(i+1) - groupStartRow(i)
422 <       groupMaxCutoff(i) = 0.0_dp
422 >       groupMaxCutoffRow(i) = 0.0_dp
423         do ia = groupStartRow(i), groupStartRow(i+1)-1
424            atom1 = groupListRow(ia)
425   #ifdef IS_MPI
# Line 359 | Line 427 | contains
427   #else
428            me_i = atid(atom1)
429   #endif          
430 <          if (atypeMaxCutoff(me_i).gt.groupMaxCutoff(i)) then
431 <             groupMaxCutoff(i)=atypeMaxCutoff(me_i)
430 >          if (atypeMaxCutoff(me_i).gt.groupMaxCutoffRow(i)) then
431 >             groupMaxCutoffRow(i)=atypeMaxCutoff(me_i)
432            endif          
433         enddo
434  
435 <       if (nGroupTypes.eq.0) then
436 <          nGroupTypes = nGroupTypes + 1
437 <          gtypeMaxCutoff(nGroupTypes) = groupMaxCutoff(i)
438 <          groupToGtype(i) = nGroupTypes
435 >       if (nGroupTypesRow.eq.0) then
436 >          nGroupTypesRow = nGroupTypesRow + 1
437 >          gtypeMaxCutoffRow(nGroupTypesRow) = groupMaxCutoffRow(i)
438 >          groupToGtypeRow(i) = nGroupTypesRow
439         else
440            GtypeFound = .false.
441 <          do g = 1, nGroupTypes
442 <             if ( abs(groupMaxCutoff(i) - gtypeMaxCutoff(g)).lt.tol) then
443 <                groupToGtype(i) = g
441 >          do g = 1, nGroupTypesRow
442 >             if ( abs(groupMaxCutoffRow(i) - gtypeMaxCutoffRow(g)).lt.tol) then
443 >                groupToGtypeRow(i) = g
444                  GtypeFound = .true.
445               endif
446            enddo
447            if (.not.GtypeFound) then            
448 <             nGroupTypes = nGroupTypes + 1
449 <             gtypeMaxCutoff(nGroupTypes) = groupMaxCutoff(i)
450 <             groupToGtype(i) = nGroupTypes
448 >             nGroupTypesRow = nGroupTypesRow + 1
449 >             gtypeMaxCutoffRow(nGroupTypesRow) = groupMaxCutoffRow(i)
450 >             groupToGtypeRow(i) = nGroupTypesRow
451            endif
452         endif
453      enddo    
454  
455 + #ifdef IS_MPI
456 +    do j = jstart, jend      
457 +       n_in_j = groupStartCol(j+1) - groupStartCol(j)
458 +       groupMaxCutoffCol(j) = 0.0_dp
459 +       do ja = groupStartCol(j), groupStartCol(j+1)-1
460 +          atom1 = groupListCol(ja)
461 +
462 +          me_j = atid_col(atom1)
463 +
464 +          if (atypeMaxCutoff(me_j).gt.groupMaxCutoffCol(j)) then
465 +             groupMaxCutoffCol(j)=atypeMaxCutoff(me_j)
466 +          endif          
467 +       enddo
468 +
469 +       if (nGroupTypesCol.eq.0) then
470 +          nGroupTypesCol = nGroupTypesCol + 1
471 +          gtypeMaxCutoffCol(nGroupTypesCol) = groupMaxCutoffCol(j)
472 +          groupToGtypeCol(j) = nGroupTypesCol
473 +       else
474 +          GtypeFound = .false.
475 +          do g = 1, nGroupTypesCol
476 +             if ( abs(groupMaxCutoffCol(j) - gtypeMaxCutoffCol(g)).lt.tol) then
477 +                groupToGtypeCol(j) = g
478 +                GtypeFound = .true.
479 +             endif
480 +          enddo
481 +          if (.not.GtypeFound) then            
482 +             nGroupTypesCol = nGroupTypesCol + 1
483 +             gtypeMaxCutoffCol(nGroupTypesCol) = groupMaxCutoffCol(j)
484 +             groupToGtypeCol(j) = nGroupTypesCol
485 +          endif
486 +       endif
487 +    enddo    
488 +
489 + #else
490 + ! Set pointers to information we just found
491 +    nGroupTypesCol = nGroupTypesRow
492 +    groupToGtypeCol => groupToGtypeRow
493 +    gtypeMaxCutoffCol => gtypeMaxCutoffRow
494 +    groupMaxCutoffCol => groupMaxCutoffRow
495 + #endif
496 +
497 +
498 +
499 +
500 +
501      !! allocate the gtypeCutoffMap here.
502 <    allocate(gtypeCutoffMap(nGroupTypes,nGroupTypes))
502 >    allocate(gtypeCutoffMap(nGroupTypesRow,nGroupTypesCol))
503      !! then we do a double loop over all the group TYPES to find the cutoff
504      !! map between groups of two types
505 <    
506 <    do i = 1, nGroupTypes
507 <       do j = 1, nGroupTypes
505 >    tradRcut = max(maxval(gtypeMaxCutoffRow),maxval(gtypeMaxCutoffCol))
506 >
507 >    do i = 1, nGroupTypesRow
508 >       do j = 1, nGroupTypesCol
509        
510            select case(cutoffPolicy)
511            case(TRADITIONAL_CUTOFF_POLICY)
512 <             thisRcut = maxval(gtypeMaxCutoff)
512 >             thisRcut = tradRcut
513            case(MIX_CUTOFF_POLICY)
514 <             thisRcut = 0.5_dp * (gtypeMaxCutoff(i) + gtypeMaxCutoff(j))
514 >             thisRcut = 0.5_dp * (gtypeMaxCutoffRow(i) + gtypeMaxCutoffCol(j))
515            case(MAX_CUTOFF_POLICY)
516 <             thisRcut = max(gtypeMaxCutoff(i), gtypeMaxCutoff(j))
516 >             thisRcut = max(gtypeMaxCutoffRow(i), gtypeMaxCutoffCol(j))
517            case default
518               call handleError("createGtypeCutoffMap", "Unknown Cutoff Policy")
519               return
# Line 406 | Line 521 | contains
521            gtypeCutoffMap(i,j)%rcut = thisRcut
522            gtypeCutoffMap(i,j)%rcutsq = thisRcut*thisRcut
523            skin = defaultRlist - defaultRcut
524 +          listSkin = skin ! set neighbor list skin thickness
525            gtypeCutoffMap(i,j)%rlistsq = (thisRcut + skin)**2
526  
527 +          ! sanity check
528 +
529 +          if (haveDefaultCutoffs) then
530 +             if (abs(gtypeCutoffMap(i,j)%rcut - defaultRcut).gt.0.0001) then
531 +                call handleError("createGtypeCutoffMap", "user-specified rCut does not match computed group Cutoff")
532 +             endif
533 +          endif
534         enddo
535      enddo
536 +    if(allocated(gtypeMaxCutoffRow)) deallocate(gtypeMaxCutoffRow)
537 +    if(allocated(groupMaxCutoffRow)) deallocate(groupMaxCutoffRow)
538 +    if(allocated(atypeMaxCutoff)) deallocate(atypeMaxCutoff)
539 + #ifdef IS_MPI
540 +    if(associated(groupMaxCutoffCol)) deallocate(groupMaxCutoffCol)
541 +    if(associated(gtypeMaxCutoffCol)) deallocate(gtypeMaxCutoffCol)
542 + #endif
543 +    groupMaxCutoffCol => null()
544 +    gtypeMaxCutoffCol => null()
545      
546      haveGtypeCutoffMap = .true.
547     end subroutine createGtypeCutoffMap
# Line 422 | Line 554 | contains
554       defaultRsw = defRsw
555       defaultRlist = defRlist
556       cutoffPolicy = cutPolicy
557 <     rcuti = 1.0_dp / defaultRcut
557 >
558 >     haveDefaultCutoffs = .true.
559     end subroutine setDefaultCutoffs
560  
561     subroutine setCutoffPolicy(cutPolicy)
# Line 439 | Line 572 | contains
572      SIM_requires_postpair_calc = SimRequiresPostpairCalc()
573      SIM_requires_prepair_calc = SimRequiresPrepairCalc()
574      SIM_uses_PBC = SimUsesPBC()
442    SIM_uses_RF = SimUsesRF()
575  
576      haveSIMvariables = .true.
577  
# Line 506 | Line 638 | contains
638    end subroutine doReadyCheck
639  
640  
641 <  subroutine init_FF(use_RF, correctionMethod, dampingAlpha, thisStat)
641 >  subroutine init_FF(thisESM, thisStat)
642  
643 <    logical, intent(in) :: use_RF
512 <    integer, intent(in) :: correctionMethod
513 <    real(kind=dp), intent(in) :: dampingAlpha
643 >    integer, intent(in) :: thisESM
644      integer, intent(out) :: thisStat  
645      integer :: my_status, nMatches
646      integer, pointer :: MatchList(:) => null()
517    real(kind=dp) :: rcut, rrf, rt, dielect
647  
648      !! assume things are copacetic, unless they aren't
649      thisStat = 0
650  
651 <    !! Fortran's version of a cast:
523 <    FF_uses_RF = use_RF
651 >    electrostaticSummationMethod = thisESM
652  
525        
653      !! init_FF is called *after* all of the atom types have been
654      !! defined in atype_module using the new_atype subroutine.
655      !!
# Line 552 | Line 679 | contains
679  
680      haveSaneForceField = .true.
681  
555    !! check to make sure the FF_uses_RF setting makes sense
556
557    if (FF_uses_Dipoles) then
558       if (FF_uses_RF) then
559          dielect = getDielect()
560          call initialize_rf(dielect)
561       endif
562    else
563       if ((corrMethod == 3) .or. FF_uses_RF) then
564          write(default_error,*) 'Using Reaction Field with no dipoles?  Huh?'
565          thisStat = -1
566          haveSaneForceField = .false.
567          return
568       endif
569    endif
570
682      if (FF_uses_EAM) then
683         call init_EAM_FF(my_status)
684         if (my_status /= 0) then
# Line 578 | Line 689 | contains
689         end if
690      endif
691  
581    if (FF_uses_GayBerne) then
582       call check_gb_pair_FF(my_status)
583       if (my_status .ne. 0) then
584          thisStat = -1
585          haveSaneForceField = .false.
586          return
587       endif
588    endif
589
692      if (.not. haveNeighborList) then
693         !! Create neighbor lists
694         call expandNeighborList(nLocal, my_status)
# Line 620 | Line 722 | contains
722  
723      !! Stress Tensor
724      real( kind = dp), dimension(9) :: tau  
725 <    real ( kind = dp ) :: pot
725 >    real ( kind = dp ),dimension(LR_POT_TYPES) :: pot
726      logical ( kind = 2) :: do_pot_c, do_stress_c
727      logical :: do_pot
728      logical :: do_stress
729      logical :: in_switching_region
730   #ifdef IS_MPI
731 <    real( kind = DP ) :: pot_local
731 >    real( kind = DP ), dimension(LR_POT_TYPES) :: pot_local
732      integer :: nAtomsInRow
733      integer :: nAtomsInCol
734      integer :: nprocs
# Line 641 | Line 743 | contains
743      integer :: nlist
744      real( kind = DP ) :: ratmsq, rgrpsq, rgrp, vpair, vij
745      real( kind = DP ) :: sw, dswdr, swderiv, mf
746 +    real( kind = DP ) :: rVal
747      real(kind=dp),dimension(3) :: d_atm, d_grp, fpair, fij
748 +    real(kind=dp), dimension(3) :: fstrs, f2strs
749      real(kind=dp) :: rfpot, mu_i, virial
750      integer :: me_i, me_j, n_in_i, n_in_j
751      logical :: is_dp_i
# Line 651 | Line 755 | contains
755      integer :: propPack_i, propPack_j
756      integer :: loopStart, loopEnd, loop
757      integer :: iHash
758 <    real(kind=dp) :: listSkin = 1.0  
758 >    integer :: i1
759 >  
760  
761      !! initialize local variables  
762  
# Line 776 | Line 881 | contains
881               me_j = atid(j)
882               call get_interatomic_vector(q_group(:,i), &
883                    q_group(:,j), d_grp, rgrpsq)
884 < #endif
884 > #endif      
885  
886 <             if (rgrpsq < gtypeCutoffMap(groupToGtype(i),groupToGtype(j))%rListsq) then
886 >             if (rgrpsq < gtypeCutoffMap(groupToGtypeRow(i),groupToGtypeCol(j))%rListsq) then
887                  if (update_nlist) then
888                     nlist = nlist + 1
889  
# Line 798 | Line 903 | contains
903  
904                     list(nlist) = j
905                  endif
906 +                
907 +                if (rgrpsq < gtypeCutoffMap(groupToGtypeRow(i),groupToGtypeCol(j))%rCutsq) then
908  
909 <                if (loop .eq. PAIR_LOOP) then
910 <                   vij = 0.0d0
911 <                   fij(1:3) = 0.0d0
912 <                endif
913 <
914 <                call get_switch(rgrpsq, sw, dswdr, rgrp, group_switch, &
915 <                     in_switching_region)
916 <
917 <                n_in_j = groupStartCol(j+1) - groupStartCol(j)
918 <
919 <                do ia = groupStartRow(i), groupStartRow(i+1)-1
920 <
921 <                   atom1 = groupListRow(ia)
922 <
923 <                   inner: do jb = groupStartCol(j), groupStartCol(j+1)-1
924 <
925 <                      atom2 = groupListCol(jb)
926 <
927 <                      if (skipThisPair(atom1, atom2)) cycle inner
928 <
929 <                      if ((n_in_i .eq. 1).and.(n_in_j .eq. 1)) then
930 <                         d_atm(1:3) = d_grp(1:3)
931 <                         ratmsq = rgrpsq
932 <                      else
909 >                   if (loop .eq. PAIR_LOOP) then
910 >                      vij = 0.0d0
911 >                      fij(1:3) = 0.0d0
912 >                   endif
913 >                  
914 >                   call get_switch(rgrpsq, sw, dswdr, rgrp, group_switch, &
915 >                        in_switching_region)
916 >                  
917 >                   n_in_j = groupStartCol(j+1) - groupStartCol(j)
918 >                  
919 >                   do ia = groupStartRow(i), groupStartRow(i+1)-1
920 >                      
921 >                      atom1 = groupListRow(ia)
922 >                      
923 >                      inner: do jb = groupStartCol(j), groupStartCol(j+1)-1
924 >                        
925 >                         atom2 = groupListCol(jb)
926 >                        
927 >                         if (skipThisPair(atom1, atom2))  cycle inner
928 >                        
929 >                         if ((n_in_i .eq. 1).and.(n_in_j .eq. 1)) then
930 >                            d_atm(1:3) = d_grp(1:3)
931 >                            ratmsq = rgrpsq
932 >                         else
933   #ifdef IS_MPI
934 <                         call get_interatomic_vector(q_Row(:,atom1), &
935 <                              q_Col(:,atom2), d_atm, ratmsq)
934 >                            call get_interatomic_vector(q_Row(:,atom1), &
935 >                                 q_Col(:,atom2), d_atm, ratmsq)
936   #else
937 <                         call get_interatomic_vector(q(:,atom1), &
938 <                              q(:,atom2), d_atm, ratmsq)
937 >                            call get_interatomic_vector(q(:,atom1), &
938 >                                 q(:,atom2), d_atm, ratmsq)
939   #endif
940 <                      endif
941 <
942 <                      if (loop .eq. PREPAIR_LOOP) then
940 >                         endif
941 >                        
942 >                         if (loop .eq. PREPAIR_LOOP) then
943   #ifdef IS_MPI                      
944 <                         call do_prepair(atom1, atom2, ratmsq, d_atm, sw, &
945 <                              rgrpsq, d_grp, do_pot, do_stress, &
946 <                              eFrame, A, f, t, pot_local)
947 < #else
948 <                         call do_prepair(atom1, atom2, ratmsq, d_atm, sw, &
949 <                              rgrpsq, d_grp, do_pot, do_stress, &
950 <                              eFrame, A, f, t, pot)
944 >                            call do_prepair(atom1, atom2, ratmsq, d_atm, sw, &
945 >                                 rgrpsq, d_grp, do_pot, do_stress, &
946 >                                 eFrame, A, f, t, pot_local)
947 > #else
948 >                            call do_prepair(atom1, atom2, ratmsq, d_atm, sw, &
949 >                                 rgrpsq, d_grp, do_pot, do_stress, &
950 >                                 eFrame, A, f, t, pot)
951   #endif                                              
952 <                      else
952 >                         else
953   #ifdef IS_MPI                      
954 <                         call do_pair(atom1, atom2, ratmsq, d_atm, sw, &
955 <                              do_pot, &
956 <                              eFrame, A, f, t, pot_local, vpair, fpair)
954 >                            call do_pair(atom1, atom2, ratmsq, d_atm, sw, &
955 >                                 do_pot, eFrame, A, f, t, pot_local, vpair, &
956 >                                 fpair, d_grp, rgrp, fstrs)
957   #else
958 <                         call do_pair(atom1, atom2, ratmsq, d_atm, sw, &
959 <                              do_pot,  &
960 <                              eFrame, A, f, t, pot, vpair, fpair)
958 >                            call do_pair(atom1, atom2, ratmsq, d_atm, sw, &
959 >                                 do_pot, eFrame, A, f, t, pot, vpair, fpair, &
960 >                                 d_grp, rgrp, fstrs)
961   #endif
962 +                            f2strs(1:3) = f2strs(1:3) + fstrs(1:3)
963 +                            vij = vij + vpair
964 +                            fij(1:3) = fij(1:3) + fpair(1:3)
965 +                         endif
966 +                      enddo inner
967 +                   enddo
968  
969 <                         vij = vij + vpair
970 <                         fij(1:3) = fij(1:3) + fpair(1:3)
971 <                      endif
972 <                   enddo inner
973 <                enddo
974 <
975 <                if (loop .eq. PAIR_LOOP) then
976 <                   if (in_switching_region) then
977 <                      swderiv = vij*dswdr/rgrp
978 <                      fij(1) = fij(1) + swderiv*d_grp(1)
866 <                      fij(2) = fij(2) + swderiv*d_grp(2)
867 <                      fij(3) = fij(3) + swderiv*d_grp(3)
868 <
869 <                      do ia=groupStartRow(i), groupStartRow(i+1)-1
870 <                         atom1=groupListRow(ia)
871 <                         mf = mfactRow(atom1)
969 >                   if (loop .eq. PAIR_LOOP) then
970 >                      if (in_switching_region) then
971 >                         swderiv = vij*dswdr/rgrp
972 >                         fij(1) = fij(1) + swderiv*d_grp(1)
973 >                         fij(2) = fij(2) + swderiv*d_grp(2)
974 >                         fij(3) = fij(3) + swderiv*d_grp(3)
975 >                        
976 >                         do ia=groupStartRow(i), groupStartRow(i+1)-1
977 >                            atom1=groupListRow(ia)
978 >                            mf = mfactRow(atom1)
979   #ifdef IS_MPI
980 <                         f_Row(1,atom1) = f_Row(1,atom1) + swderiv*d_grp(1)*mf
981 <                         f_Row(2,atom1) = f_Row(2,atom1) + swderiv*d_grp(2)*mf
982 <                         f_Row(3,atom1) = f_Row(3,atom1) + swderiv*d_grp(3)*mf
980 >                            f_Row(1,atom1) = f_Row(1,atom1) + swderiv*d_grp(1)*mf
981 >                            f_Row(2,atom1) = f_Row(2,atom1) + swderiv*d_grp(2)*mf
982 >                            f_Row(3,atom1) = f_Row(3,atom1) + swderiv*d_grp(3)*mf
983   #else
984 <                         f(1,atom1) = f(1,atom1) + swderiv*d_grp(1)*mf
985 <                         f(2,atom1) = f(2,atom1) + swderiv*d_grp(2)*mf
986 <                         f(3,atom1) = f(3,atom1) + swderiv*d_grp(3)*mf
984 >                            f(1,atom1) = f(1,atom1) + swderiv*d_grp(1)*mf
985 >                            f(2,atom1) = f(2,atom1) + swderiv*d_grp(2)*mf
986 >                            f(3,atom1) = f(3,atom1) + swderiv*d_grp(3)*mf
987   #endif
988 <                      enddo
989 <
990 <                      do jb=groupStartCol(j), groupStartCol(j+1)-1
991 <                         atom2=groupListCol(jb)
992 <                         mf = mfactCol(atom2)
988 >                         enddo
989 >                        
990 >                         do jb=groupStartCol(j), groupStartCol(j+1)-1
991 >                            atom2=groupListCol(jb)
992 >                            mf = mfactCol(atom2)
993   #ifdef IS_MPI
994 <                         f_Col(1,atom2) = f_Col(1,atom2) - swderiv*d_grp(1)*mf
995 <                         f_Col(2,atom2) = f_Col(2,atom2) - swderiv*d_grp(2)*mf
996 <                         f_Col(3,atom2) = f_Col(3,atom2) - swderiv*d_grp(3)*mf
994 >                            f_Col(1,atom2) = f_Col(1,atom2) - swderiv*d_grp(1)*mf
995 >                            f_Col(2,atom2) = f_Col(2,atom2) - swderiv*d_grp(2)*mf
996 >                            f_Col(3,atom2) = f_Col(3,atom2) - swderiv*d_grp(3)*mf
997   #else
998 <                         f(1,atom2) = f(1,atom2) - swderiv*d_grp(1)*mf
999 <                         f(2,atom2) = f(2,atom2) - swderiv*d_grp(2)*mf
1000 <                         f(3,atom2) = f(3,atom2) - swderiv*d_grp(3)*mf
998 >                            f(1,atom2) = f(1,atom2) - swderiv*d_grp(1)*mf
999 >                            f(2,atom2) = f(2,atom2) - swderiv*d_grp(2)*mf
1000 >                            f(3,atom2) = f(3,atom2) - swderiv*d_grp(3)*mf
1001   #endif
1002 <                      enddo
1003 <                   endif
1002 >                         enddo
1003 >                      endif
1004  
1005 <                   if (do_stress) call add_stress_tensor(d_grp, fij)
1005 >                      if (do_stress) call add_stress_tensor(d_grp, fij)
1006 >                   endif
1007                  endif
1008 <             end if
1008 >             endif
1009            enddo
1010 +          
1011         enddo outer
1012  
1013         if (update_nlist) then
# Line 958 | Line 1067 | contains
1067  
1068      if (do_pot) then
1069         ! scatter/gather pot_row into the members of my column
1070 <       call scatter(pot_Row, pot_Temp, plan_atom_row)
1071 <
1070 >       do i = 1,LR_POT_TYPES
1071 >          call scatter(pot_Row(i,:), pot_Temp(i,:), plan_atom_row)
1072 >       end do
1073         ! scatter/gather pot_local into all other procs
1074         ! add resultant to get total pot
1075         do i = 1, nlocal
1076 <          pot_local = pot_local + pot_Temp(i)
1076 >          pot_local(1:LR_POT_TYPES) = pot_local(1:LR_POT_TYPES) &
1077 >               + pot_Temp(1:LR_POT_TYPES,i)
1078         enddo
1079  
1080         pot_Temp = 0.0_DP
1081 <
1082 <       call scatter(pot_Col, pot_Temp, plan_atom_col)
1081 >       do i = 1,LR_POT_TYPES
1082 >          call scatter(pot_Col(i,:), pot_Temp(i,:), plan_atom_col)
1083 >       end do
1084         do i = 1, nlocal
1085 <          pot_local = pot_local + pot_Temp(i)
1085 >          pot_local(1:LR_POT_TYPES) = pot_local(1:LR_POT_TYPES)&
1086 >               + pot_Temp(1:LR_POT_TYPES,i)
1087         enddo
1088  
1089      endif
1090   #endif
1091  
1092 <    if (FF_RequiresPostpairCalc() .and. SIM_requires_postpair_calc) then
1092 >    if (SIM_requires_postpair_calc) then
1093 >       do i = 1, nlocal            
1094 >          
1095 >          ! we loop only over the local atoms, so we don't need row and column
1096 >          ! lookups for the types
1097 >          
1098 >          me_i = atid(i)
1099 >          
1100 >          ! is the atom electrostatic?  See if it would have an
1101 >          ! electrostatic interaction with itself
1102 >          iHash = InteractionHash(me_i,me_i)
1103  
1104 <       if ((FF_uses_RF .and. SIM_uses_RF) .or. (corrMethod == 3)) then
982 <
1104 >          if ( iand(iHash, ELECTROSTATIC_PAIR).ne.0 ) then
1105   #ifdef IS_MPI
1106 <          call scatter(rf_Row,rf,plan_atom_row_3d)
1107 <          call scatter(rf_Col,rf_Temp,plan_atom_col_3d)
986 <          do i = 1,nlocal
987 <             rf(1:3,i) = rf(1:3,i) + rf_Temp(1:3,i)
988 <          end do
989 < #endif
990 <
991 <          do i = 1, nLocal
992 <
993 <             rfpot = 0.0_DP
994 < #ifdef IS_MPI
995 <             me_i = atid_row(i)
1106 >             call self_self(i, eFrame, pot_local(ELECTROSTATIC_POT), &
1107 >                  t, do_pot)
1108   #else
1109 <             me_i = atid(i)
1109 >             call self_self(i, eFrame, pot(ELECTROSTATIC_POT), &
1110 >                  t, do_pot)
1111   #endif
1112 <             iHash = InteractionHash(me_i,me_j)
1112 >          endif
1113 >  
1114 >          
1115 >          if (electrostaticSummationMethod.eq.REACTION_FIELD) then
1116              
1117 <             if ( iand(iHash, ELECTROSTATIC_PAIR).ne.0 ) then
1118 <
1119 <                mu_i = getDipoleMoment(me_i)
1120 <
1121 <                !! The reaction field needs to include a self contribution
1122 <                !! to the field:
1123 <                call accumulate_self_rf(i, mu_i, eFrame)
1124 <                !! Get the reaction field contribution to the
1125 <                !! potential and torques:
1126 <                call reaction_field_final(i, mu_i, eFrame, rfpot, t, do_pot)
1117 >             ! loop over the excludes to accumulate RF stuff we've
1118 >             ! left out of the normal pair loop
1119 >            
1120 >             do i1 = 1, nSkipsForAtom(i)
1121 >                j = skipsForAtom(i, i1)
1122 >                
1123 >                ! prevent overcounting of the skips
1124 >                if (i.lt.j) then
1125 >                   call get_interatomic_vector(q(:,i), &
1126 >                        q(:,j), d_atm, ratmsq)
1127 >                   rVal = dsqrt(ratmsq)
1128 >                   call get_switch(ratmsq, sw, dswdr, rVal, group_switch, &
1129 >                        in_switching_region)
1130   #ifdef IS_MPI
1131 <                pot_local = pot_local + rfpot
1131 >                   call rf_self_excludes(i, j, sw, eFrame, d_atm, rVal, &
1132 >                        vpair, pot_local(ELECTROSTATIC_POT), f, t, do_pot)
1133   #else
1134 <                pot = pot + rfpot
1135 <
1134 >                   call rf_self_excludes(i, j, sw, eFrame, d_atm, rVal, &
1135 >                        vpair, pot(ELECTROSTATIC_POT), f, t, do_pot)
1136   #endif
1137 <             endif
1138 <          enddo
1139 <       endif
1137 >                endif
1138 >             enddo
1139 >          endif
1140 >       enddo
1141      endif
1142 <
1022 <
1142 >    
1143   #ifdef IS_MPI
1144 <
1144 >    
1145      if (do_pot) then
1146 <       pot = pot + pot_local
1147 <       !! we assume the c code will do the allreduce to get the total potential
1028 <       !! we could do it right here if we needed to...
1146 >       call mpi_allreduce(pot_local, pot, LR_POT_TYPES,mpi_double_precision,mpi_sum, &
1147 >            mpi_comm_world,mpi_err)            
1148      endif
1149 <
1149 >    
1150      if (do_stress) then
1151         call mpi_allreduce(tau_Temp, tau, 9,mpi_double_precision,mpi_sum, &
1152              mpi_comm_world,mpi_err)
1153         call mpi_allreduce(virial_Temp, virial,1,mpi_double_precision,mpi_sum, &
1154              mpi_comm_world,mpi_err)
1155      endif
1156 <
1156 >    
1157   #else
1158 <
1158 >    
1159      if (do_stress) then
1160         tau = tau_Temp
1161         virial = virial_Temp
1162      endif
1163 <
1163 >    
1164   #endif
1165 <
1165 >    
1166    end subroutine do_force_loop
1167  
1168 + !!$  subroutine do_pair(i, j, rijsq, d, sw, do_pot, &
1169 + !!$       eFrame, A, f, t, pot, vpair, fpair, d_grp, r_grp)
1170    subroutine do_pair(i, j, rijsq, d, sw, do_pot, &
1171 <       eFrame, A, f, t, pot, vpair, fpair)
1171 >       eFrame, A, f, t, pot, vpair, fpair, d_grp, r_grp, fstrs)
1172  
1173 <    real( kind = dp ) :: pot, vpair, sw
1173 >    real( kind = dp ) :: vpair, sw
1174 >    real( kind = dp ), dimension(LR_POT_TYPES) :: pot
1175      real( kind = dp ), dimension(3) :: fpair
1176 +    real( kind = dp ), dimension(3) :: fstrs
1177      real( kind = dp ), dimension(nLocal)   :: mfact
1178      real( kind = dp ), dimension(9,nLocal) :: eFrame
1179      real( kind = dp ), dimension(9,nLocal) :: A
# Line 1060 | Line 1183 | contains
1183      logical, intent(inout) :: do_pot
1184      integer, intent(in) :: i, j
1185      real ( kind = dp ), intent(inout) :: rijsq
1186 <    real ( kind = dp )                :: r
1186 >    real ( kind = dp ), intent(inout) :: r_grp
1187      real ( kind = dp ), intent(inout) :: d(3)
1188 +    real ( kind = dp ), intent(inout) :: d_grp(3)
1189 +    real ( kind = dp ) :: r
1190      integer :: me_i, me_j
1191  
1192      integer :: iHash
# Line 1079 | Line 1204 | contains
1204   #endif
1205  
1206      iHash = InteractionHash(me_i, me_j)
1207 <
1207 >    
1208      if ( iand(iHash, LJ_PAIR).ne.0 ) then
1209 <       call do_lj_pair(i, j, d, r, rijsq, sw, vpair, fpair, pot, f, do_pot)
1209 >       call do_lj_pair(i, j, d, r, rijsq, sw, vpair, fpair, &
1210 >            pot(VDW_POT), f, do_pot)
1211      endif
1212 <
1212 >    
1213      if ( iand(iHash, ELECTROSTATIC_PAIR).ne.0 ) then
1214 + !!$       call doElectrostaticPair(i, j, d, r, rijsq, sw, vpair, fpair, &
1215 + !!$            pot(ELECTROSTATIC_POT), eFrame, f, t, do_pot)
1216         call doElectrostaticPair(i, j, d, r, rijsq, sw, vpair, fpair, &
1217 <            pot, eFrame, f, t, do_pot, corrMethod, rcuti)
1090 <
1091 <       if ((FF_uses_RF .and. SIM_uses_RF) .or. (corrMethod == 3)) then
1092 <
1093 <          ! CHECK ME (RF needs to know about all electrostatic types)
1094 <          call accumulate_rf(i, j, r, eFrame, sw)
1095 <          call rf_correct_forces(i, j, d, r, eFrame, sw, f, fpair)
1096 <       endif
1097 <
1217 >            pot(ELECTROSTATIC_POT), eFrame, f, t, do_pot, fstrs)
1218      endif
1219 <
1219 >    
1220      if ( iand(iHash, STICKY_PAIR).ne.0 ) then
1221         call do_sticky_pair(i, j, d, r, rijsq, sw, vpair, fpair, &
1222 <            pot, A, f, t, do_pot)
1222 >            pot(HB_POT), A, f, t, do_pot)
1223      endif
1224 <
1224 >    
1225      if ( iand(iHash, STICKYPOWER_PAIR).ne.0 ) then
1226         call do_sticky_power_pair(i, j, d, r, rijsq, sw, vpair, fpair, &
1227 <            pot, A, f, t, do_pot)
1227 >            pot(HB_POT), A, f, t, do_pot)
1228      endif
1229 <
1229 >    
1230      if ( iand(iHash, GAYBERNE_PAIR).ne.0 ) then
1231         call do_gb_pair(i, j, d, r, rijsq, sw, vpair, fpair, &
1232 <            pot, A, f, t, do_pot)
1232 >            pot(VDW_POT), A, f, t, do_pot)
1233      endif
1234      
1235      if ( iand(iHash, GAYBERNE_LJ).ne.0 ) then
1236 < !      call do_gblj_pair(i, j, d, r, rijsq, sw, vpair, fpair, &
1237 < !           pot, A, f, t, do_pot)
1236 >       call do_gb_lj_pair(i, j, d, r, rijsq, sw, vpair, fpair, &
1237 >            pot(VDW_POT), A, f, t, do_pot)
1238      endif
1239 <
1239 >    
1240      if ( iand(iHash, EAM_PAIR).ne.0 ) then      
1241 <       call do_eam_pair(i, j, d, r, rijsq, sw, vpair, fpair, pot, f, &
1242 <            do_pot)
1241 >       call do_eam_pair(i, j, d, r, rijsq, sw, vpair, fpair, &
1242 >            pot(METALLIC_POT), f, do_pot)
1243      endif
1244 <
1244 >    
1245      if ( iand(iHash, SHAPE_PAIR).ne.0 ) then      
1246         call do_shape_pair(i, j, d, r, rijsq, sw, vpair, fpair, &
1247 <            pot, A, f, t, do_pot)
1247 >            pot(VDW_POT), A, f, t, do_pot)
1248      endif
1249 <
1249 >    
1250      if ( iand(iHash, SHAPE_LJ).ne.0 ) then      
1251         call do_shape_pair(i, j, d, r, rijsq, sw, vpair, fpair, &
1252 <            pot, A, f, t, do_pot)
1252 >            pot(VDW_POT), A, f, t, do_pot)
1253      endif
1254 <    
1254 >    
1255    end subroutine do_pair
1256  
1257    subroutine do_prepair(i, j, rijsq, d, sw, rcijsq, dc, &
1258         do_pot, do_stress, eFrame, A, f, t, pot)
1259  
1260 <    real( kind = dp ) :: pot, sw
1260 >    real( kind = dp ) :: sw
1261 >    real( kind = dp ), dimension(LR_POT_TYPES) :: pot
1262      real( kind = dp ), dimension(9,nLocal) :: eFrame
1263      real (kind=dp), dimension(9,nLocal) :: A
1264      real (kind=dp), dimension(3,nLocal) :: f
# Line 1172 | Line 1293 | contains
1293  
1294    subroutine do_preforce(nlocal,pot)
1295      integer :: nlocal
1296 <    real( kind = dp ) :: pot
1296 >    real( kind = dp ),dimension(LR_POT_TYPES) :: pot
1297  
1298      if (FF_uses_EAM .and. SIM_uses_EAM) then
1299 <       call calc_EAM_preforce_Frho(nlocal,pot)
1299 >       call calc_EAM_preforce_Frho(nlocal,pot(METALLIC_POT))
1300      endif
1301  
1302  
# Line 1260 | Line 1381 | contains
1381      pot_Row = 0.0_dp
1382      pot_Col = 0.0_dp
1383      pot_Temp = 0.0_dp
1263
1264    rf_Row = 0.0_dp
1265    rf_Col = 0.0_dp
1266    rf_Temp = 0.0_dp
1384  
1385   #endif
1386  
# Line 1271 | Line 1388 | contains
1388         call clean_EAM()
1389      endif
1390  
1274    rf = 0.0_dp
1391      tau_Temp = 0.0_dp
1392      virial_Temp = 0.0_dp
1393    end subroutine zero_work_arrays
# Line 1368 | Line 1484 | contains
1484      doesit = FF_uses_EAM
1485    end function FF_RequiresPrepairCalc
1486  
1371  function FF_RequiresPostpairCalc() result(doesit)
1372    logical :: doesit
1373    doesit = FF_uses_RF
1374    if (corrMethod == 3) doesit = .true.
1375  end function FF_RequiresPostpairCalc
1376
1487   #ifdef PROFILE
1488    function getforcetime() result(totalforcetime)
1489      real(kind=dp) :: totalforcetime

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines