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 2220 by chrisfen, Thu May 5 14:47:35 2005 UTC vs.
Revision 2226 by kdaily, Tue May 17 02:09:25 2005 UTC

# Line 45 | Line 45
45  
46   !! @author Charles F. Vardeman II
47   !! @author Matthew Meineke
48 < !! @version $Id: doForces.F90,v 1.15 2005-05-05 14:47:35 chrisfen Exp $, $Date: 2005-05-05 14:47:35 $, $Name: not supported by cvs2svn $, $Revision: 1.15 $
48 > !! @version $Id: doForces.F90,v 1.16 2005-05-17 02:09:06 kdaily Exp $, $Date: 2005-05-17 02:09:06 $, $Name: not supported by cvs2svn $, $Revision: 1.16 $
49  
50  
51   module doForces
# Line 82 | Line 82 | module doForces
82    logical, save :: haveSIMvariables = .false.
83    logical, save :: havePropertyMap = .false.
84    logical, save :: haveSaneForceField = .false.
85 <
85 >  
86    logical, save :: FF_uses_DirectionalAtoms
87    logical, save :: FF_uses_LennardJones
88    logical, save :: FF_uses_Electrostatics
89    logical, save :: FF_uses_Charges
90    logical, save :: FF_uses_Dipoles
91    logical, save :: FF_uses_Quadrupoles
92 <  logical, save :: FF_uses_Sticky
93 <  logical, save :: FF_uses_StickyPower
92 >  logical, save :: FF_uses_sticky
93    logical, save :: FF_uses_GayBerne
94    logical, save :: FF_uses_EAM
95    logical, save :: FF_uses_Shapes
# Line 104 | Line 103 | module doForces
103    logical, save :: SIM_uses_Dipoles
104    logical, save :: SIM_uses_Quadrupoles
105    logical, save :: SIM_uses_Sticky
107  logical, save :: SIM_uses_StickyPower
106    logical, save :: SIM_uses_GayBerne
107    logical, save :: SIM_uses_EAM
108    logical, save :: SIM_uses_Shapes
# Line 136 | Line 134 | module doForces
134       logical :: is_Dipole        = .false.
135       logical :: is_Quadrupole    = .false.
136       logical :: is_Sticky        = .false.
139     logical :: is_StickyPower   = .false.
137       logical :: is_GayBerne      = .false.
138       logical :: is_EAM           = .false.
139       logical :: is_Shape         = .false.
# Line 148 | Line 145 | contains
145   contains
146  
147    subroutine setRlistDF( this_rlist )
148 <
148 >    
149      real(kind=dp) :: this_rlist
150  
151      rlist = this_rlist
152      rlistsq = rlist * rlist
153 <
153 >    
154      haveRlist = .true.
155  
156 <  end subroutine setRlistDF
156 >  end subroutine setRlistDF    
157  
158    subroutine createPropertyMap(status)
159      integer :: nAtypes
# Line 173 | Line 170 | contains
170         status = -1
171         return
172      end if
173 <
173 >        
174      if (.not. allocated(PropertyMap)) then
175         allocate(PropertyMap(nAtypes))
176      endif
# Line 184 | Line 181 | contains
181  
182         call getElementProperty(atypes, i, "is_LennardJones", thisProperty)
183         PropertyMap(i)%is_LennardJones = thisProperty
184 <
184 >      
185         call getElementProperty(atypes, i, "is_Electrostatic", thisProperty)
186         PropertyMap(i)%is_Electrostatic = thisProperty
187  
188         call getElementProperty(atypes, i, "is_Charge", thisProperty)
189         PropertyMap(i)%is_Charge = thisProperty
190 <
190 >      
191         call getElementProperty(atypes, i, "is_Dipole", thisProperty)
192         PropertyMap(i)%is_Dipole = thisProperty
193  
# Line 199 | Line 196 | contains
196  
197         call getElementProperty(atypes, i, "is_Sticky", thisProperty)
198         PropertyMap(i)%is_Sticky = thisProperty
202      
203       call getElementProperty(atypes, i, "is_StickyPower", thisProperty)
204       PropertyMap(i)%is_StickyPower = thisProperty
199  
200         call getElementProperty(atypes, i, "is_GayBerne", thisProperty)
201         PropertyMap(i)%is_GayBerne = thisProperty
# Line 227 | Line 221 | contains
221      SIM_uses_Charges = SimUsesCharges()
222      SIM_uses_Dipoles = SimUsesDipoles()
223      SIM_uses_Sticky = SimUsesSticky()
230    SIM_uses_StickyPower = SimUsesStickyPower()
224      SIM_uses_GayBerne = SimUsesGayBerne()
225      SIM_uses_EAM = SimUsesEAM()
226      SIM_uses_Shapes = SimUsesShapes()
# Line 248 | Line 241 | contains
241      integer :: myStatus
242  
243      error = 0
244 <
244 >    
245      if (.not. havePropertyMap) then
246  
247         myStatus = 0
# Line 293 | Line 286 | contains
286   #endif
287      return
288    end subroutine doReadyCheck
289 +    
290  
297
291    subroutine init_FF(use_RF_c, thisStat)
292  
293      logical, intent(in) :: use_RF_c
# Line 309 | Line 302 | contains
302  
303      !! Fortran's version of a cast:
304      FF_uses_RF = use_RF_c
305 <
305 >    
306      !! init_FF is called *after* all of the atom types have been
307      !! defined in atype_module using the new_atype subroutine.
308      !!
309      !! this will scan through the known atypes and figure out what
310      !! interactions are used by the force field.    
311 <
311 >  
312      FF_uses_DirectionalAtoms = .false.
313      FF_uses_LennardJones = .false.
314      FF_uses_Electrostatics = .false.
315      FF_uses_Charges = .false.    
316      FF_uses_Dipoles = .false.
317      FF_uses_Sticky = .false.
325    FF_uses_StickyPower = .false.
318      FF_uses_GayBerne = .false.
319      FF_uses_EAM = .false.
320      FF_uses_Shapes = .false.
321      FF_uses_FLARB = .false.
322 <
322 >    
323      call getMatchingElementList(atypes, "is_Directional", .true., &
324           nMatches, MatchList)
325      if (nMatches .gt. 0) FF_uses_DirectionalAtoms = .true.
# Line 335 | Line 327 | contains
327      call getMatchingElementList(atypes, "is_LennardJones", .true., &
328           nMatches, MatchList)
329      if (nMatches .gt. 0) FF_uses_LennardJones = .true.
330 <
330 >    
331      call getMatchingElementList(atypes, "is_Electrostatic", .true., &
332           nMatches, MatchList)
333      if (nMatches .gt. 0) then
# Line 348 | Line 340 | contains
340         FF_uses_Charges = .true.  
341         FF_uses_Electrostatics = .true.
342      endif
343 <
343 >    
344      call getMatchingElementList(atypes, "is_Dipole", .true., &
345           nMatches, MatchList)
346      if (nMatches .gt. 0) then
# Line 364 | Line 356 | contains
356         FF_uses_Electrostatics = .true.
357         FF_uses_DirectionalAtoms = .true.
358      endif
359 <
359 >    
360      call getMatchingElementList(atypes, "is_Sticky", .true., nMatches, &
361           MatchList)
362      if (nMatches .gt. 0) then
363         FF_uses_Sticky = .true.
364         FF_uses_DirectionalAtoms = .true.
365      endif
374
375    call getMatchingElementList(atypes, "is_StickyPower", .true., nMatches, &
376         MatchList)
377    if (nMatches .gt. 0) then
378       FF_uses_StickyPower = .true.
379       FF_uses_DirectionalAtoms = .true.
380    endif
366      
367      call getMatchingElementList(atypes, "is_GayBerne", .true., &
368           nMatches, MatchList)
# Line 385 | Line 370 | contains
370         FF_uses_GayBerne = .true.
371         FF_uses_DirectionalAtoms = .true.
372      endif
373 <
373 >    
374      call getMatchingElementList(atypes, "is_EAM", .true., nMatches, MatchList)
375      if (nMatches .gt. 0) FF_uses_EAM = .true.
376 <
376 >    
377      call getMatchingElementList(atypes, "is_Shape", .true., &
378           nMatches, MatchList)
379      if (nMatches .gt. 0) then
# Line 402 | Line 387 | contains
387  
388      !! Assume sanity (for the sake of argument)
389      haveSaneForceField = .true.
390 <
390 >    
391      !! check to make sure the FF_uses_RF setting makes sense
392 <
392 >    
393      if (FF_uses_dipoles) then
394         if (FF_uses_RF) then
395            dielect = getDielect()
# Line 417 | Line 402 | contains
402            haveSaneForceField = .false.
403            return
404         endif
405 <    endif
405 >    endif
406  
407      !sticky module does not contain check_sticky_FF anymore
408      !if (FF_uses_sticky) then
# Line 430 | Line 415 | contains
415      !endif
416  
417      if (FF_uses_EAM) then
418 <       call init_EAM_FF(my_status)
418 >         call init_EAM_FF(my_status)
419         if (my_status /= 0) then
420            write(default_error, *) "init_EAM_FF returned a bad status"
421            thisStat = -1
# Line 450 | Line 435 | contains
435  
436      if (FF_uses_GayBerne .and. FF_uses_LennardJones) then
437      endif
438 <
438 >    
439      if (.not. haveNeighborList) then
440         !! Create neighbor lists
441         call expandNeighborList(nLocal, my_status)
# Line 460 | Line 445 | contains
445            return
446         endif
447         haveNeighborList = .true.
448 <    endif
449 <
448 >    endif    
449 >    
450    end subroutine init_FF
451 +  
452  
467
453    !! Does force loop over i,j pairs. Calls do_pair to calculates forces.
454    !------------------------------------------------------------->
455    subroutine do_force_loop(q, q_group, A, eFrame, f, t, tau, pot, &
# Line 516 | Line 501 | contains
501      integer :: loopStart, loopEnd, loop
502  
503      real(kind=dp) :: listSkin = 1.0  
504 <
504 >    
505      !! initialize local variables  
506 <
506 >    
507   #ifdef IS_MPI
508      pot_local = 0.0_dp
509      nAtomsInRow   = getNatomsInRow(plan_atom_row)
# Line 528 | Line 513 | contains
513   #else
514      natoms = nlocal
515   #endif
516 <
516 >    
517      call doReadyCheck(localError)
518      if ( localError .ne. 0 ) then
519         call handleError("do_force_loop", "Not Initialized")
# Line 536 | Line 521 | contains
521         return
522      end if
523      call zero_work_arrays()
524 <
524 >        
525      do_pot = do_pot_c
526      do_stress = do_stress_c
527 <
527 >    
528      ! Gather all information needed by all force loops:
529 <
529 >    
530   #ifdef IS_MPI    
531 <
531 >    
532      call gather(q, q_Row, plan_atom_row_3d)
533      call gather(q, q_Col, plan_atom_col_3d)
534  
535      call gather(q_group, q_group_Row, plan_group_row_3d)
536      call gather(q_group, q_group_Col, plan_group_col_3d)
537 <
537 >        
538      if (FF_UsesDirectionalAtoms() .and. SIM_uses_DirectionalAtoms) then
539         call gather(eFrame, eFrame_Row, plan_atom_row_rotation)
540         call gather(eFrame, eFrame_Col, plan_atom_col_rotation)
541 <
541 >      
542         call gather(A, A_Row, plan_atom_row_rotation)
543         call gather(A, A_Col, plan_atom_col_rotation)
544      endif
545 <
545 >    
546   #endif
547 <
547 >    
548      !! Begin force loop timing:
549   #ifdef PROFILE
550      call cpu_time(forceTimeInitial)
551      nloops = nloops + 1
552   #endif
553 <
553 >    
554      loopEnd = PAIR_LOOP
555      if (FF_RequiresPrepairCalc() .and. SIM_requires_prepair_calc) then
556         loopStart = PREPAIR_LOOP
# Line 580 | Line 565 | contains
565         if (loop .eq. loopStart) then
566   #ifdef IS_MPI
567            call checkNeighborList(nGroupsInRow, q_group_row, listSkin, &
568 <               update_nlist)
568 >             update_nlist)
569   #else
570            call checkNeighborList(nGroups, q_group, listSkin, &
571 <               update_nlist)
571 >             update_nlist)
572   #endif
573         endif
574 <
574 >      
575         if (update_nlist) then
576            !! save current configuration and construct neighbor list
577   #ifdef IS_MPI
# Line 597 | Line 582 | contains
582            neighborListSize = size(list)
583            nlist = 0
584         endif
585 <
585 >      
586         istart = 1
587   #ifdef IS_MPI
588         iend = nGroupsInRow
# Line 607 | Line 592 | contains
592         outer: do i = istart, iend
593  
594            if (update_nlist) point(i) = nlist + 1
595 <
595 >          
596            n_in_i = groupStartRow(i+1) - groupStartRow(i)
597 <
597 >          
598            if (update_nlist) then
599   #ifdef IS_MPI
600               jstart = 1
# Line 624 | Line 609 | contains
609               ! make sure group i has neighbors
610               if (jstart .gt. jend) cycle outer
611            endif
612 <
612 >          
613            do jnab = jstart, jend
614               if (update_nlist) then
615                  j = jnab
# Line 643 | Line 628 | contains
628               if (rgrpsq < rlistsq) then
629                  if (update_nlist) then
630                     nlist = nlist + 1
631 <
631 >                  
632                     if (nlist > neighborListSize) then
633   #ifdef IS_MPI                
634                        call expandNeighborList(nGroupsInRow, listerror)
# Line 657 | Line 642 | contains
642                        end if
643                        neighborListSize = size(list)
644                     endif
645 <
645 >                  
646                     list(nlist) = j
647                  endif
648 <
648 >                
649                  if (loop .eq. PAIR_LOOP) then
650                     vij = 0.0d0
651                     fij(1:3) = 0.0d0
652                  endif
653 <
653 >                
654                  call get_switch(rgrpsq, sw, dswdr, rgrp, group_switch, &
655                       in_switching_region)
656 <
656 >                
657                  n_in_j = groupStartCol(j+1) - groupStartCol(j)
658 <
658 >                
659                  do ia = groupStartRow(i), groupStartRow(i+1)-1
660 <
660 >                  
661                     atom1 = groupListRow(ia)
662 <
662 >                  
663                     inner: do jb = groupStartCol(j), groupStartCol(j+1)-1
664 <
664 >                      
665                        atom2 = groupListCol(jb)
666 <
666 >                      
667                        if (skipThisPair(atom1, atom2)) cycle inner
668  
669                        if ((n_in_i .eq. 1).and.(n_in_j .eq. 1)) then
# Line 720 | Line 705 | contains
705                        endif
706                     enddo inner
707                  enddo
708 <
708 >                
709                  if (loop .eq. PAIR_LOOP) then
710                     if (in_switching_region) then
711                        swderiv = vij*dswdr/rgrp
712                        fij(1) = fij(1) + swderiv*d_grp(1)
713                        fij(2) = fij(2) + swderiv*d_grp(2)
714                        fij(3) = fij(3) + swderiv*d_grp(3)
715 <
715 >                      
716                        do ia=groupStartRow(i), groupStartRow(i+1)-1
717                           atom1=groupListRow(ia)
718                           mf = mfactRow(atom1)
# Line 741 | Line 726 | contains
726                           f(3,atom1) = f(3,atom1) + swderiv*d_grp(3)*mf
727   #endif
728                        enddo
729 <
729 >                      
730                        do jb=groupStartCol(j), groupStartCol(j+1)-1
731                           atom2=groupListCol(jb)
732                           mf = mfactCol(atom2)
# Line 756 | Line 741 | contains
741   #endif
742                        enddo
743                     endif
744 <
744 >                  
745                     if (do_stress) call add_stress_tensor(d_grp, fij)
746                  endif
747               end if
748            enddo
749         enddo outer
750 <
750 >      
751         if (update_nlist) then
752   #ifdef IS_MPI
753            point(nGroupsInRow + 1) = nlist + 1
# Line 776 | Line 761 | contains
761               update_nlist = .false.                              
762            endif
763         endif
764 <
764 >            
765         if (loop .eq. PREPAIR_LOOP) then
766            call do_preforce(nlocal, pot)
767         endif
768 <
768 >      
769      enddo
770 <
770 >    
771      !! Do timing
772   #ifdef PROFILE
773      call cpu_time(forceTimeFinal)
774      forceTime = forceTime + forceTimeFinal - forceTimeInitial
775   #endif    
776 <
776 >    
777   #ifdef IS_MPI
778      !!distribute forces
779 <
779 >    
780      f_temp = 0.0_dp
781      call scatter(f_Row,f_temp,plan_atom_row_3d)
782      do i = 1,nlocal
783         f(1:3,i) = f(1:3,i) + f_temp(1:3,i)
784      end do
785 <
785 >    
786      f_temp = 0.0_dp
787      call scatter(f_Col,f_temp,plan_atom_col_3d)
788      do i = 1,nlocal
789         f(1:3,i) = f(1:3,i) + f_temp(1:3,i)
790      end do
791 <
791 >    
792      if (FF_UsesDirectionalAtoms() .and. SIM_uses_DirectionalAtoms) then
793         t_temp = 0.0_dp
794         call scatter(t_Row,t_temp,plan_atom_row_3d)
# Line 812 | Line 797 | contains
797         end do
798         t_temp = 0.0_dp
799         call scatter(t_Col,t_temp,plan_atom_col_3d)
800 <
800 >      
801         do i = 1,nlocal
802            t(1:3,i) = t(1:3,i) + t_temp(1:3,i)
803         end do
804      endif
805 <
805 >    
806      if (do_pot) then
807         ! scatter/gather pot_row into the members of my column
808         call scatter(pot_Row, pot_Temp, plan_atom_row)
809 <
809 >      
810         ! scatter/gather pot_local into all other procs
811         ! add resultant to get total pot
812         do i = 1, nlocal
813            pot_local = pot_local + pot_Temp(i)
814         enddo
815 <
815 >      
816         pot_Temp = 0.0_DP
817 <
817 >      
818         call scatter(pot_Col, pot_Temp, plan_atom_col)
819         do i = 1, nlocal
820            pot_local = pot_local + pot_Temp(i)
821         enddo
822 <
822 >      
823      endif
824   #endif
825 <
825 >    
826      if (FF_RequiresPostpairCalc() .and. SIM_requires_postpair_calc) then
827 <
827 >      
828         if (FF_uses_RF .and. SIM_uses_RF) then
829 <
829 >          
830   #ifdef IS_MPI
831            call scatter(rf_Row,rf,plan_atom_row_3d)
832            call scatter(rf_Col,rf_Temp,plan_atom_col_3d)
# Line 849 | Line 834 | contains
834               rf(1:3,i) = rf(1:3,i) + rf_Temp(1:3,i)
835            end do
836   #endif
837 <
837 >          
838            do i = 1, nLocal
839 <
839 >            
840               rfpot = 0.0_DP
841   #ifdef IS_MPI
842               me_i = atid_row(i)
843   #else
844               me_i = atid(i)
845   #endif
846 <
846 >            
847               if (PropertyMap(me_i)%is_Dipole) then
848 <
848 >                
849                  mu_i = getDipoleMoment(me_i)
850 <
850 >    
851                  !! The reaction field needs to include a self contribution
852                  !! to the field:
853                  call accumulate_self_rf(i, mu_i, eFrame)
# Line 873 | Line 858 | contains
858                  pot_local = pot_local + rfpot
859   #else
860                  pot = pot + rfpot
861 <
861 >      
862   #endif
863 <             endif
863 >             endif            
864            enddo
865         endif
866      endif
867 <
868 <
867 >    
868 >    
869   #ifdef IS_MPI
870 <
870 >    
871      if (do_pot) then
872         pot = pot + pot_local
873         !! we assume the c code will do the allreduce to get the total potential
874         !! we could do it right here if we needed to...
875      endif
876 <
876 >    
877      if (do_stress) then
878         call mpi_allreduce(tau_Temp, tau, 9,mpi_double_precision,mpi_sum, &
879              mpi_comm_world,mpi_err)
880         call mpi_allreduce(virial_Temp, virial,1,mpi_double_precision,mpi_sum, &
881              mpi_comm_world,mpi_err)
882      endif
883 <
883 >    
884   #else
885 <
885 >    
886      if (do_stress) then
887         tau = tau_Temp
888         virial = virial_Temp
889      endif
890 <
890 >    
891   #endif
892 <
892 >      
893    end subroutine do_force_loop
894 <
894 >  
895    subroutine do_pair(i, j, rijsq, d, sw, do_pot, &
896         eFrame, A, f, t, pot, vpair, fpair)
897  
# Line 936 | Line 921 | contains
921      me_i = atid(i)
922      me_j = atid(j)
923   #endif
939
940    !    write(*,*) i, j, me_i, me_j
924  
925 + !    write(*,*) i, j, me_i, me_j
926 +    
927      if (FF_uses_LennardJones .and. SIM_uses_LennardJones) then
928 <
928 >      
929         if ( PropertyMap(me_i)%is_LennardJones .and. &
930              PropertyMap(me_j)%is_LennardJones ) then
931            call do_lj_pair(i, j, d, r, rijsq, sw, vpair, fpair, pot, f, do_pot)
932         endif
933 <
933 >      
934      endif
935 <
935 >    
936      if (FF_uses_Electrostatics .and. SIM_uses_Electrostatics) then
937 <
937 >      
938         if (PropertyMap(me_i)%is_Electrostatic .and. &
939              PropertyMap(me_j)%is_Electrostatic) then
940            call doElectrostaticPair(i, j, d, r, rijsq, sw, vpair, fpair, &
941                 pot, eFrame, f, t, do_pot)
942         endif
943 <
943 >      
944         if (FF_uses_dipoles .and. SIM_uses_dipoles) then      
945            if ( PropertyMap(me_i)%is_Dipole .and. &
946                 PropertyMap(me_j)%is_Dipole) then
# Line 974 | Line 959 | contains
959            call do_sticky_pair(i, j, d, r, rijsq, sw, vpair, fpair, &
960                 pot, A, f, t, do_pot)
961         endif
962 <
962 >      
963      endif
964  
980    if (FF_uses_StickyPower .and. SIM_uses_stickypower) then
981       if ( PropertyMap(me_i)%is_StickyPower .and. &
982            PropertyMap(me_j)%is_StickyPower) then
983          call do_sticky_power_pair(i, j, d, r, rijsq, sw, vpair, fpair, &
984               pot, A, f, t, do_pot)
985       endif
986    endif
987    
988    if (FF_uses_GayBerne .and. SIM_uses_GayBerne) then
965  
966 +    if (FF_uses_GayBerne .and. SIM_uses_GayBerne) then
967 +      
968         if ( PropertyMap(me_i)%is_GayBerne .and. &
969              PropertyMap(me_j)%is_GayBerne) then
970            call do_gb_pair(i, j, d, r, rijsq, sw, vpair, fpair, &
971                 pot, A, f, t, do_pot)
972         endif
973 <
973 >      
974      endif
975 <
975 >    
976      if (FF_uses_EAM .and. SIM_uses_EAM) then
977 <
977 >      
978         if ( PropertyMap(me_i)%is_EAM .and. PropertyMap(me_j)%is_EAM) then
979            call do_eam_pair(i, j, d, r, rijsq, sw, vpair, fpair, pot, f, &
980                 do_pot)
981         endif
982 <
982 >      
983      endif
984  
985  
986 <    !    write(*,*) PropertyMap(me_i)%is_Shape,PropertyMap(me_j)%is_Shape
986 > !    write(*,*) PropertyMap(me_i)%is_Shape,PropertyMap(me_j)%is_Shape
987  
988      if (FF_uses_Shapes .and. SIM_uses_Shapes) then
989         if ( PropertyMap(me_i)%is_Shape .and. &
# Line 1013 | Line 991 | contains
991            call do_shape_pair(i, j, d, r, rijsq, sw, vpair, fpair, &
992                 pot, A, f, t, do_pot)
993         endif
994 <       if ( (PropertyMap(me_i)%is_Shape .and. &
1017 <            PropertyMap(me_j)%is_LennardJones) .or. &
1018 <            (PropertyMap(me_i)%is_LennardJones .and. &
1019 <            PropertyMap(me_j)%is_Shape) ) then
1020 <          call do_shape_pair(i, j, d, r, rijsq, sw, vpair, fpair, &
1021 <               pot, A, f, t, do_pot)
1022 <       endif
994 >      
995      endif
996 <
996 >    
997    end subroutine do_pair
998  
999    subroutine do_prepair(i, j, rijsq, d, sw, rcijsq, dc, &
1000         do_pot, do_stress, eFrame, A, f, t, pot)
1001  
1002 <    real( kind = dp ) :: pot, sw
1003 <    real( kind = dp ), dimension(9,nLocal) :: eFrame
1004 <    real (kind=dp), dimension(9,nLocal) :: A
1005 <    real (kind=dp), dimension(3,nLocal) :: f
1006 <    real (kind=dp), dimension(3,nLocal) :: t
1002 >   real( kind = dp ) :: pot, sw
1003 >   real( kind = dp ), dimension(9,nLocal) :: eFrame
1004 >   real (kind=dp), dimension(9,nLocal) :: A
1005 >   real (kind=dp), dimension(3,nLocal) :: f
1006 >   real (kind=dp), dimension(3,nLocal) :: t
1007 >  
1008 >   logical, intent(inout) :: do_pot, do_stress
1009 >   integer, intent(in) :: i, j
1010 >   real ( kind = dp ), intent(inout)    :: rijsq, rcijsq
1011 >   real ( kind = dp )                :: r, rc
1012 >   real ( kind = dp ), intent(inout) :: d(3), dc(3)
1013 >  
1014 >   logical :: is_EAM_i, is_EAM_j
1015 >  
1016 >   integer :: me_i, me_j
1017 >  
1018  
1036    logical, intent(inout) :: do_pot, do_stress
1037    integer, intent(in) :: i, j
1038    real ( kind = dp ), intent(inout)    :: rijsq, rcijsq
1039    real ( kind = dp )                :: r, rc
1040    real ( kind = dp ), intent(inout) :: d(3), dc(3)
1041
1042    logical :: is_EAM_i, is_EAM_j
1043
1044    integer :: me_i, me_j
1045
1046
1019      r = sqrt(rijsq)
1020      if (SIM_uses_molecular_cutoffs) then
1021         rc = sqrt(rcijsq)
1022      else
1023         rc = r
1024      endif
1025 +  
1026  
1054
1027   #ifdef IS_MPI  
1028 <    me_i = atid_row(i)
1029 <    me_j = atid_col(j)  
1028 >   me_i = atid_row(i)
1029 >   me_j = atid_col(j)  
1030   #else  
1031 <    me_i = atid(i)
1032 <    me_j = atid(j)  
1031 >   me_i = atid(i)
1032 >   me_j = atid(j)  
1033   #endif
1034 <
1035 <    if (FF_uses_EAM .and. SIM_uses_EAM) then
1036 <
1037 <       if (PropertyMap(me_i)%is_EAM .and. PropertyMap(me_j)%is_EAM) &
1038 <            call calc_EAM_prepair_rho(i, j, d, r, rijsq )
1039 <
1040 <    endif
1041 <
1042 <  end subroutine do_prepair
1043 <
1044 <
1045 <  subroutine do_preforce(nlocal,pot)
1046 <    integer :: nlocal
1047 <    real( kind = dp ) :: pot
1048 <
1049 <    if (FF_uses_EAM .and. SIM_uses_EAM) then
1050 <       call calc_EAM_preforce_Frho(nlocal,pot)
1051 <    endif
1052 <
1053 <
1054 <  end subroutine do_preforce
1055 <
1056 <
1057 <  subroutine get_interatomic_vector(q_i, q_j, d, r_sq)
1058 <
1059 <    real (kind = dp), dimension(3) :: q_i
1060 <    real (kind = dp), dimension(3) :: q_j
1061 <    real ( kind = dp ), intent(out) :: r_sq
1062 <    real( kind = dp ) :: d(3), scaled(3)
1063 <    integer i
1064 <
1065 <    d(1:3) = q_j(1:3) - q_i(1:3)
1066 <
1067 <    ! Wrap back into periodic box if necessary
1068 <    if ( SIM_uses_PBC ) then
1069 <
1070 <       if( .not.boxIsOrthorhombic ) then
1071 <          ! calc the scaled coordinates.
1072 <
1073 <          scaled = matmul(HmatInv, d)
1074 <
1075 <          ! wrap the scaled coordinates
1076 <
1077 <          scaled = scaled  - anint(scaled)
1078 <
1079 <
1080 <          ! calc the wrapped real coordinates from the wrapped scaled
1081 <          ! coordinates
1082 <
1083 <          d = matmul(Hmat,scaled)
1084 <
1085 <       else
1086 <          ! calc the scaled coordinates.
1087 <
1088 <          do i = 1, 3
1089 <             scaled(i) = d(i) * HmatInv(i,i)
1090 <
1091 <             ! wrap the scaled coordinates
1092 <
1093 <             scaled(i) = scaled(i) - anint(scaled(i))
1094 <
1095 <             ! calc the wrapped real coordinates from the wrapped scaled
1096 <             ! coordinates
1097 <
1098 <             d(i) = scaled(i)*Hmat(i,i)
1099 <          enddo
1100 <       endif
1101 <
1102 <    endif
1103 <
1104 <    r_sq = dot_product(d,d)
1105 <
1106 <  end subroutine get_interatomic_vector
1107 <
1108 <  subroutine zero_work_arrays()
1109 <
1034 >  
1035 >   if (FF_uses_EAM .and. SIM_uses_EAM) then
1036 >      
1037 >      if (PropertyMap(me_i)%is_EAM .and. PropertyMap(me_j)%is_EAM) &
1038 >           call calc_EAM_prepair_rho(i, j, d, r, rijsq )
1039 >      
1040 >   endif
1041 >  
1042 > end subroutine do_prepair
1043 >
1044 >
1045 > subroutine do_preforce(nlocal,pot)
1046 >   integer :: nlocal
1047 >   real( kind = dp ) :: pot
1048 >  
1049 >   if (FF_uses_EAM .and. SIM_uses_EAM) then
1050 >      call calc_EAM_preforce_Frho(nlocal,pot)
1051 >   endif
1052 >  
1053 >  
1054 > end subroutine do_preforce
1055 >
1056 >
1057 > subroutine get_interatomic_vector(q_i, q_j, d, r_sq)
1058 >  
1059 >   real (kind = dp), dimension(3) :: q_i
1060 >   real (kind = dp), dimension(3) :: q_j
1061 >   real ( kind = dp ), intent(out) :: r_sq
1062 >   real( kind = dp ) :: d(3), scaled(3)
1063 >   integer i
1064 >  
1065 >   d(1:3) = q_j(1:3) - q_i(1:3)
1066 >  
1067 >   ! Wrap back into periodic box if necessary
1068 >   if ( SIM_uses_PBC ) then
1069 >      
1070 >      if( .not.boxIsOrthorhombic ) then
1071 >         ! calc the scaled coordinates.
1072 >        
1073 >         scaled = matmul(HmatInv, d)
1074 >        
1075 >         ! wrap the scaled coordinates
1076 >        
1077 >         scaled = scaled  - anint(scaled)
1078 >        
1079 >        
1080 >         ! calc the wrapped real coordinates from the wrapped scaled
1081 >         ! coordinates
1082 >        
1083 >         d = matmul(Hmat,scaled)
1084 >        
1085 >      else
1086 >         ! calc the scaled coordinates.
1087 >        
1088 >         do i = 1, 3
1089 >            scaled(i) = d(i) * HmatInv(i,i)
1090 >            
1091 >            ! wrap the scaled coordinates
1092 >            
1093 >            scaled(i) = scaled(i) - anint(scaled(i))
1094 >            
1095 >            ! calc the wrapped real coordinates from the wrapped scaled
1096 >            ! coordinates
1097 >            
1098 >            d(i) = scaled(i)*Hmat(i,i)
1099 >         enddo
1100 >      endif
1101 >      
1102 >   endif
1103 >  
1104 >   r_sq = dot_product(d,d)
1105 >  
1106 > end subroutine get_interatomic_vector
1107 >
1108 > subroutine zero_work_arrays()
1109 >  
1110   #ifdef IS_MPI
1111 +  
1112 +   q_Row = 0.0_dp
1113 +   q_Col = 0.0_dp
1114  
1115 <    q_Row = 0.0_dp
1116 <    q_Col = 0.0_dp
1117 <
1118 <    q_group_Row = 0.0_dp
1119 <    q_group_Col = 0.0_dp  
1120 <
1121 <    eFrame_Row = 0.0_dp
1122 <    eFrame_Col = 0.0_dp
1123 <
1124 <    A_Row = 0.0_dp
1125 <    A_Col = 0.0_dp
1126 <
1127 <    f_Row = 0.0_dp
1128 <    f_Col = 0.0_dp
1129 <    f_Temp = 0.0_dp
1130 <
1131 <    t_Row = 0.0_dp
1132 <    t_Col = 0.0_dp
1133 <    t_Temp = 0.0_dp
1134 <
1135 <    pot_Row = 0.0_dp
1136 <    pot_Col = 0.0_dp
1137 <    pot_Temp = 0.0_dp
1138 <
1139 <    rf_Row = 0.0_dp
1165 <    rf_Col = 0.0_dp
1166 <    rf_Temp = 0.0_dp
1167 <
1115 >   q_group_Row = 0.0_dp
1116 >   q_group_Col = 0.0_dp  
1117 >  
1118 >   eFrame_Row = 0.0_dp
1119 >   eFrame_Col = 0.0_dp
1120 >  
1121 >   A_Row = 0.0_dp
1122 >   A_Col = 0.0_dp
1123 >  
1124 >   f_Row = 0.0_dp
1125 >   f_Col = 0.0_dp
1126 >   f_Temp = 0.0_dp
1127 >  
1128 >   t_Row = 0.0_dp
1129 >   t_Col = 0.0_dp
1130 >   t_Temp = 0.0_dp
1131 >  
1132 >   pot_Row = 0.0_dp
1133 >   pot_Col = 0.0_dp
1134 >   pot_Temp = 0.0_dp
1135 >  
1136 >   rf_Row = 0.0_dp
1137 >   rf_Col = 0.0_dp
1138 >   rf_Temp = 0.0_dp
1139 >  
1140   #endif
1141 <
1142 <    if (FF_uses_EAM .and. SIM_uses_EAM) then
1143 <       call clean_EAM()
1144 <    endif
1145 <
1146 <    rf = 0.0_dp
1147 <    tau_Temp = 0.0_dp
1148 <    virial_Temp = 0.0_dp
1149 <  end subroutine zero_work_arrays
1150 <
1151 <  function skipThisPair(atom1, atom2) result(skip_it)
1152 <    integer, intent(in) :: atom1
1153 <    integer, intent(in), optional :: atom2
1154 <    logical :: skip_it
1155 <    integer :: unique_id_1, unique_id_2
1156 <    integer :: me_i,me_j
1157 <    integer :: i
1158 <
1159 <    skip_it = .false.
1160 <
1161 <    !! there are a number of reasons to skip a pair or a particle
1162 <    !! mostly we do this to exclude atoms who are involved in short
1163 <    !! range interactions (bonds, bends, torsions), but we also need
1164 <    !! to exclude some overcounted interactions that result from
1165 <    !! the parallel decomposition
1166 <
1141 >
1142 >   if (FF_uses_EAM .and. SIM_uses_EAM) then
1143 >      call clean_EAM()
1144 >   endif
1145 >  
1146 >   rf = 0.0_dp
1147 >   tau_Temp = 0.0_dp
1148 >   virial_Temp = 0.0_dp
1149 > end subroutine zero_work_arrays
1150 >
1151 > function skipThisPair(atom1, atom2) result(skip_it)
1152 >   integer, intent(in) :: atom1
1153 >   integer, intent(in), optional :: atom2
1154 >   logical :: skip_it
1155 >   integer :: unique_id_1, unique_id_2
1156 >   integer :: me_i,me_j
1157 >   integer :: i
1158 >  
1159 >   skip_it = .false.
1160 >  
1161 >   !! there are a number of reasons to skip a pair or a particle
1162 >   !! mostly we do this to exclude atoms who are involved in short
1163 >   !! range interactions (bonds, bends, torsions), but we also need
1164 >   !! to exclude some overcounted interactions that result from
1165 >   !! the parallel decomposition
1166 >  
1167   #ifdef IS_MPI
1168 <    !! in MPI, we have to look up the unique IDs for each atom
1169 <    unique_id_1 = AtomRowToGlobal(atom1)
1168 >   !! in MPI, we have to look up the unique IDs for each atom
1169 >   unique_id_1 = AtomRowToGlobal(atom1)
1170   #else
1171 <    !! in the normal loop, the atom numbers are unique
1172 <    unique_id_1 = atom1
1171 >   !! in the normal loop, the atom numbers are unique
1172 >   unique_id_1 = atom1
1173   #endif
1174 <
1175 <    !! We were called with only one atom, so just check the global exclude
1176 <    !! list for this atom
1177 <    if (.not. present(atom2)) then
1178 <       do i = 1, nExcludes_global
1179 <          if (excludesGlobal(i) == unique_id_1) then
1180 <             skip_it = .true.
1181 <             return
1182 <          end if
1183 <       end do
1184 <       return
1185 <    end if
1186 <
1174 >  
1175 >   !! We were called with only one atom, so just check the global exclude
1176 >   !! list for this atom
1177 >   if (.not. present(atom2)) then
1178 >      do i = 1, nExcludes_global
1179 >         if (excludesGlobal(i) == unique_id_1) then
1180 >            skip_it = .true.
1181 >            return
1182 >         end if
1183 >      end do
1184 >      return
1185 >   end if
1186 >  
1187   #ifdef IS_MPI
1188 <    unique_id_2 = AtomColToGlobal(atom2)
1188 >   unique_id_2 = AtomColToGlobal(atom2)
1189   #else
1190 <    unique_id_2 = atom2
1190 >   unique_id_2 = atom2
1191   #endif
1192 <
1192 >  
1193   #ifdef IS_MPI
1194 <    !! this situation should only arise in MPI simulations
1195 <    if (unique_id_1 == unique_id_2) then
1196 <       skip_it = .true.
1197 <       return
1198 <    end if
1199 <
1200 <    !! this prevents us from doing the pair on multiple processors
1201 <    if (unique_id_1 < unique_id_2) then
1202 <       if (mod(unique_id_1 + unique_id_2,2) == 0) then
1203 <          skip_it = .true.
1204 <          return
1205 <       endif
1206 <    else                
1207 <       if (mod(unique_id_1 + unique_id_2,2) == 1) then
1208 <          skip_it = .true.
1209 <          return
1210 <       endif
1211 <    endif
1194 >   !! this situation should only arise in MPI simulations
1195 >   if (unique_id_1 == unique_id_2) then
1196 >      skip_it = .true.
1197 >      return
1198 >   end if
1199 >  
1200 >   !! this prevents us from doing the pair on multiple processors
1201 >   if (unique_id_1 < unique_id_2) then
1202 >      if (mod(unique_id_1 + unique_id_2,2) == 0) then
1203 >         skip_it = .true.
1204 >         return
1205 >      endif
1206 >   else                
1207 >      if (mod(unique_id_1 + unique_id_2,2) == 1) then
1208 >         skip_it = .true.
1209 >         return
1210 >      endif
1211 >   endif
1212   #endif
1213 <
1214 <    !! the rest of these situations can happen in all simulations:
1215 <    do i = 1, nExcludes_global      
1216 <       if ((excludesGlobal(i) == unique_id_1) .or. &
1217 <            (excludesGlobal(i) == unique_id_2)) then
1218 <          skip_it = .true.
1219 <          return
1220 <       endif
1221 <    enddo
1222 <
1223 <    do i = 1, nSkipsForAtom(atom1)
1224 <       if (skipsForAtom(atom1, i) .eq. unique_id_2) then
1225 <          skip_it = .true.
1226 <          return
1227 <       endif
1228 <    end do
1229 <
1230 <    return
1231 <  end function skipThisPair
1232 <
1233 <  function FF_UsesDirectionalAtoms() result(doesit)
1234 <    logical :: doesit
1235 <    doesit = FF_uses_DirectionalAtoms .or. FF_uses_Dipoles .or. &
1236 <         FF_uses_Quadrupoles .or. FF_uses_Sticky .or. &
1237 <         FF_uses_StickyPower .or. FF_uses_GayBerne .or. FF_uses_Shapes
1238 <  end function FF_UsesDirectionalAtoms
1239 <
1240 <  function FF_RequiresPrepairCalc() result(doesit)
1241 <    logical :: doesit
1242 <    doesit = FF_uses_EAM
1243 <  end function FF_RequiresPrepairCalc
1244 <
1245 <  function FF_RequiresPostpairCalc() result(doesit)
1246 <    logical :: doesit
1247 <    doesit = FF_uses_RF
1248 <  end function FF_RequiresPostpairCalc
1249 <
1213 >  
1214 >   !! the rest of these situations can happen in all simulations:
1215 >   do i = 1, nExcludes_global      
1216 >      if ((excludesGlobal(i) == unique_id_1) .or. &
1217 >           (excludesGlobal(i) == unique_id_2)) then
1218 >         skip_it = .true.
1219 >         return
1220 >      endif
1221 >   enddo
1222 >  
1223 >   do i = 1, nSkipsForAtom(atom1)
1224 >      if (skipsForAtom(atom1, i) .eq. unique_id_2) then
1225 >         skip_it = .true.
1226 >         return
1227 >      endif
1228 >   end do
1229 >  
1230 >   return
1231 > end function skipThisPair
1232 >
1233 > function FF_UsesDirectionalAtoms() result(doesit)
1234 >   logical :: doesit
1235 >   doesit = FF_uses_DirectionalAtoms .or. FF_uses_Dipoles .or. &
1236 >        FF_uses_Quadrupoles .or. FF_uses_Sticky .or. &
1237 >        FF_uses_GayBerne .or. FF_uses_Shapes
1238 > end function FF_UsesDirectionalAtoms
1239 >
1240 > function FF_RequiresPrepairCalc() result(doesit)
1241 >   logical :: doesit
1242 >   doesit = FF_uses_EAM
1243 > end function FF_RequiresPrepairCalc
1244 >
1245 > function FF_RequiresPostpairCalc() result(doesit)
1246 >   logical :: doesit
1247 >   doesit = FF_uses_RF
1248 > end function FF_RequiresPostpairCalc
1249 >
1250   #ifdef PROFILE
1251 <  function getforcetime() result(totalforcetime)
1252 <    real(kind=dp) :: totalforcetime
1253 <    totalforcetime = forcetime
1254 <  end function getforcetime
1251 > function getforcetime() result(totalforcetime)
1252 >   real(kind=dp) :: totalforcetime
1253 >   totalforcetime = forcetime
1254 > end function getforcetime
1255   #endif
1256 +
1257 + !! This cleans componets of force arrays belonging only to fortran
1258  
1259 <  !! This cleans componets of force arrays belonging only to fortran
1260 <
1261 <  subroutine add_stress_tensor(dpair, fpair)
1262 <
1263 <    real( kind = dp ), dimension(3), intent(in) :: dpair, fpair
1264 <
1265 <    ! because the d vector is the rj - ri vector, and
1266 <    ! because fx, fy, fz are the force on atom i, we need a
1267 <    ! negative sign here:  
1268 <
1269 <    tau_Temp(1) = tau_Temp(1) - dpair(1) * fpair(1)
1270 <    tau_Temp(2) = tau_Temp(2) - dpair(1) * fpair(2)
1271 <    tau_Temp(3) = tau_Temp(3) - dpair(1) * fpair(3)
1272 <    tau_Temp(4) = tau_Temp(4) - dpair(2) * fpair(1)
1273 <    tau_Temp(5) = tau_Temp(5) - dpair(2) * fpair(2)
1274 <    tau_Temp(6) = tau_Temp(6) - dpair(2) * fpair(3)
1275 <    tau_Temp(7) = tau_Temp(7) - dpair(3) * fpair(1)
1276 <    tau_Temp(8) = tau_Temp(8) - dpair(3) * fpair(2)
1277 <    tau_Temp(9) = tau_Temp(9) - dpair(3) * fpair(3)
1278 <
1279 <    virial_Temp = virial_Temp + &
1280 <         (tau_Temp(1) + tau_Temp(5) + tau_Temp(9))
1281 <
1308 <  end subroutine add_stress_tensor
1309 <
1259 > subroutine add_stress_tensor(dpair, fpair)
1260 >  
1261 >   real( kind = dp ), dimension(3), intent(in) :: dpair, fpair
1262 >  
1263 >   ! because the d vector is the rj - ri vector, and
1264 >   ! because fx, fy, fz are the force on atom i, we need a
1265 >   ! negative sign here:  
1266 >  
1267 >   tau_Temp(1) = tau_Temp(1) - dpair(1) * fpair(1)
1268 >   tau_Temp(2) = tau_Temp(2) - dpair(1) * fpair(2)
1269 >   tau_Temp(3) = tau_Temp(3) - dpair(1) * fpair(3)
1270 >   tau_Temp(4) = tau_Temp(4) - dpair(2) * fpair(1)
1271 >   tau_Temp(5) = tau_Temp(5) - dpair(2) * fpair(2)
1272 >   tau_Temp(6) = tau_Temp(6) - dpair(2) * fpair(3)
1273 >   tau_Temp(7) = tau_Temp(7) - dpair(3) * fpair(1)
1274 >   tau_Temp(8) = tau_Temp(8) - dpair(3) * fpair(2)
1275 >   tau_Temp(9) = tau_Temp(9) - dpair(3) * fpair(3)
1276 >  
1277 >   virial_Temp = virial_Temp + &
1278 >        (tau_Temp(1) + tau_Temp(5) + tau_Temp(9))
1279 >  
1280 > end subroutine add_stress_tensor
1281 >
1282   end module doForces

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines