ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE/libmdtools/do_Forces.F90
(Generate patch)

Comparing trunk/OOPSE/libmdtools/do_Forces.F90 (file contents):
Revision 1160 by gezelter, Tue May 11 21:31:15 2004 UTC vs.
Revision 1217 by gezelter, Tue Jun 1 21:45:22 2004 UTC

# Line 4 | Line 4
4  
5   !! @author Charles F. Vardeman II
6   !! @author Matthew Meineke
7 < !! @version $Id: do_Forces.F90,v 1.55 2004-05-11 21:31:14 gezelter Exp $, $Date: 2004-05-11 21:31:14 $, $Name: not supported by cvs2svn $, $Revision: 1.55 $
7 > !! @version $Id: do_Forces.F90,v 1.68 2004-06-01 21:45:22 gezelter Exp $, $Date: 2004-06-01 21:45:22 $, $Name: not supported by cvs2svn $, $Revision: 1.68 $
8  
9   module do_Forces
10    use force_globals
# Line 33 | Line 33 | module do_Forces
33   #include "fForceField.h"
34   #include "fSwitchingFunction.h"
35  
36 +  INTEGER, PARAMETER:: PREPAIR_LOOP = 1
37 +  INTEGER, PARAMETER:: PAIR_LOOP    = 2
38 +
39    logical, save :: haveRlist = .false.
40    logical, save :: haveNeighborList = .false.
41    logical, save :: havePolicies = .false.
# Line 370 | Line 373 | contains
373    subroutine do_force_loop(q, q_group, A, u_l, f, t, tau, pot, &
374         do_pot_c, do_stress_c, error)
375      !! Position array provided by C, dimensioned by getNlocal
376 <    real ( kind = dp ), dimension(3,nLocal) :: q
376 >    real ( kind = dp ), dimension(3, nLocal) :: q
377      !! molecular center-of-mass position array
378 <    real ( kind = dp ), dimension(3,nGroup) :: q_group
378 >    real ( kind = dp ), dimension(3, nGroups) :: q_group
379      !! Rotation Matrix for each long range particle in simulation.
380 <    real( kind = dp), dimension(9,nLocal) :: A    
380 >    real( kind = dp), dimension(9, nLocal) :: A    
381      !! Unit vectors for dipoles (lab frame)
382      real( kind = dp ), dimension(3,nLocal) :: u_l
383      !! Force array provided by C, dimensioned by getNlocal
# Line 391 | Line 394 | contains
394      logical :: in_switching_region
395   #ifdef IS_MPI
396      real( kind = DP ) :: pot_local
397 <    integer :: nrow
398 <    integer :: ncol
397 >    integer :: nAtomsInRow
398 >    integer :: nAtomsInCol
399      integer :: nprocs
400 <    integer :: nrow_group
401 <    integer :: ncol_group
400 >    integer :: nGroupsInRow
401 >    integer :: nGroupsInCol
402   #endif
403      integer :: natoms    
404      logical :: update_nlist  
405 <    integer :: i, j, jbeg, jend, jnab
405 >    integer :: i, j, jstart, jend, jnab
406 >    integer :: istart, iend
407      integer :: ia, jb, atom1, atom2
408      integer :: nlist
409 <    real( kind = DP ) :: ratmsq, rgrpsq, rgrp, vpair, vab
409 >    real( kind = DP ) :: ratmsq, rgrpsq, rgrp, vpair, vij
410      real( kind = DP ) :: sw, dswdr, swderiv, mf
411 <    real(kind=dp),dimension(3) :: d_atm, d_grp
411 >    real(kind=dp),dimension(3) :: d_atm, d_grp, fpair, fij
412      real(kind=dp) :: rfpot, mu_i, virial
413 <    integer :: me_i, me_j
413 >    integer :: me_i, me_j, n_in_i, n_in_j
414      logical :: is_dp_i
415      integer :: neighborListSize
416      integer :: listerror, error
417      integer :: localError
418      integer :: propPack_i, propPack_j
419 +    integer :: loopStart, loopEnd, loop
420  
421      real(kind=dp) :: listSkin = 1.0  
422      
# Line 419 | Line 424 | contains
424      
425   #ifdef IS_MPI
426      pot_local = 0.0_dp
427 <    nrow   = getNrow(plan_row)
428 <    ncol   = getNcol(plan_col)
429 <    nrow_group   = getNrowGroup(plan_row)
430 <    ncol_group   = getNcolGroup(plan_col)
427 >    nAtomsInRow   = getNatomsInRow(plan_atom_row)
428 >    nAtomsInCol   = getNatomsInCol(plan_atom_col)
429 >    nGroupsInRow  = getNgroupsInRow(plan_group_row)
430 >    nGroupsInCol  = getNgroupsInCol(plan_group_col)
431   #else
432      natoms = nlocal
433   #endif
# Line 442 | Line 447 | contains
447      
448   #ifdef IS_MPI    
449      
450 <    call gather(q, q_Row, plan_row3d)
451 <    call gather(q, q_Col, plan_col3d)
450 >    call gather(q, q_Row, plan_atom_row_3d)
451 >    call gather(q, q_Col, plan_atom_col_3d)
452  
453 <    call gather(q_group, q_group_Row, plan_row_Group_3d)
454 <    call gather(q_group, q_group_Col, plan_col_Group_3d)
453 >    call gather(q_group, q_group_Row, plan_group_row_3d)
454 >    call gather(q_group, q_group_Col, plan_group_col_3d)
455          
456      if (FF_UsesDirectionalAtoms() .and. SIM_uses_directional_atoms) then
457 <       call gather(u_l,u_l_Row,plan_row3d)
458 <       call gather(u_l,u_l_Col,plan_col3d)
457 >       call gather(u_l, u_l_Row, plan_atom_row_3d)
458 >       call gather(u_l, u_l_Col, plan_atom_col_3d)
459        
460 <       call gather(A,A_Row,plan_row_rotation)
461 <       call gather(A,A_Col,plan_col_rotation)
460 >       call gather(A, A_Row, plan_atom_row_rotation)
461 >       call gather(A, A_Col, plan_atom_col_rotation)
462      endif
463      
464   #endif
# Line 464 | Line 469 | contains
469      nloops = nloops + 1
470   #endif
471      
472 +    loopEnd = PAIR_LOOP
473      if (FF_RequiresPrepairCalc() .and. SIM_requires_prepair_calc) then
474 <       !! See if we need to update neighbor lists
475 <
476 <       call checkNeighborList(nGroup, q_group, listSkin, update_nlist)
474 >       loopStart = PREPAIR_LOOP
475 >    else
476 >       loopStart = PAIR_LOOP
477 >    endif
478  
479 <       !! if_mpi_gather_stuff_for_prepair
480 <       !! do_prepair_loop_if_needed
481 <       !! if_mpi_scatter_stuff_from_prepair
482 <       !! if_mpi_gather_stuff_from_prepair_to_main_loop
483 <      
477 <       !--------------------PREFORCE LOOP----------->>>>>>>>>>>>>>>>>>>>>>>>>>>
479 >    do loop = loopStart, loopEnd
480 >
481 >       ! See if we need to update neighbor lists
482 >       ! (but only on the first time through):
483 >       if (loop .eq. loopStart) then
484   #ifdef IS_MPI
485 +          call checkNeighborList(nGroupsInRow, q_group_row, listSkin, &
486 +             update_nlist)
487 + #else
488 +          call checkNeighborList(nGroups, q_group, listSkin, &
489 +             update_nlist)
490 + #endif
491 +       endif
492        
493         if (update_nlist) then
494 <          
495 <          !! save current configuration, construct neighbor list,
496 <          !! and calculate forces
497 <
498 <          call saveNeighborList(nGroup, q_group)
499 <          
494 >          !! save current configuration and construct neighbor list
495 > #ifdef IS_MPI
496 >          call saveNeighborList(nGroupsInRow, q_group_row)
497 > #else
498 >          call saveNeighborList(nGroups, q_group)
499 > #endif        
500            neighborListSize = size(list)
501 <          nlist = 0      
489 <          
490 <          do i = 1, nrow_group
491 <             point(i) = nlist + 1
492 <            
493 <             do j = 1, ncol_group
494 <                
495 <                call get_interatomic_vector(q_group_Row(:,i), &
496 <                     q_group_Col(:,j), d_grp, rgrpsq)
497 <                
498 <                if (rgrpsq < rlistsq) then
499 <                   nlist = nlist + 1
500 <                  
501 <                   if (nlist > neighborListSize) then
502 <                      call expandNeighborList(nGroup, listerror)
503 <                      if (listerror /= 0) then
504 <                         error = -1
505 <                         write(DEFAULT_ERROR,*) "ERROR: nlist > list size and max allocations exceeded."
506 <                         return
507 <                      end if
508 <                      neighborListSize = size(list)
509 <                   endif
510 <                  
511 <                   list(nlist) = j
512 <                  
513 <                   do ia = groupStart(i), groupStart(i+1)-1
514 <                      atom1 = groupList(ia)
515 <
516 <                      prepair_inner: do jb = groupStart(j), groupStart(j+1)-1
517 <                         atom2 = groupList(jb)
518 <                        
519 <                         if (skipThisPair(atom1, atom2)) cycle prepair_inner
520 <                        
521 <                         call get_interatomic_vector(q_Row(:,atom1), &
522 <                              q_Col(:,atom2), d_atm, ratmsq)
523 <                        
524 <                         call do_prepair(atom1, atom2, ratmsq, d_atm, &
525 <                              rgrpsq, d_grp, do_pot, do_stress, &
526 <                              u_l, A, f, t, pot_local)
527 <
528 <                      enddo prepair_inner
529 <                   enddo
530 <                end if
531 <             enddo
532 <          enddo
533 <          point(nrow_group + 1) = nlist + 1          
534 <                          
535 <       else  !! (of update_check)
536 <          
537 <          ! use the list to find the neighbors
538 <          do i = 1, nrow_group
539 <             JBEG = POINT(i)
540 <             JEND = POINT(i+1) - 1
541 <             ! check that group i has neighbors
542 <             if (jbeg .le. jend) then
543 <                
544 <                do jnab = jbeg, jend
545 <                   j = list(jnab)
546 <                  
547 <                   do ia = groupStart(i), groupStart(i+1)-1
548 <                      atom1 = groupList(ia)
549 <
550 <                      do jb = groupStart(j), groupStart(j+1)-1
551 <                         atom2 = groupList(jb)                        
552 <                        
553 <                         call get_interatomic_vector(q_Row(:,atom1), &
554 <                              q_Col(:,atom2), d_atm, ratmsq)
555 <                        
556 <                         call do_prepair(atom1, atom2, ratmsq, d_atm, &
557 <                              rgrpsq, d_grp, do_pot, do_stress, &
558 <                              u_l, A, f, t, pot_local)
559 <                        
560 <                      enddo
561 <                   enddo
562 <                enddo
563 <             endif
564 <          enddo
501 >          nlist = 0
502         endif
503        
504 +       istart = 1
505 + #ifdef IS_MPI
506 +       iend = nGroupsInRow
507   #else
508 +       iend = nGroups - 1
509 + #endif
510 +       outer: do i = istart, iend
511  
512 <       if (update_nlist) then
512 >          if (update_nlist) point(i) = nlist + 1
513            
514 <          !! save current configuration, construct neighbor list,
572 <          !! and calculate forces
514 >          n_in_i = groupStartRow(i+1) - groupStartRow(i)
515            
516 <          call saveNeighborList(nGroup, q_group)
516 >          if (update_nlist) then
517 > #ifdef IS_MPI
518 >             jstart = 1
519 >             jend = nGroupsInCol
520 > #else
521 >             jstart = i+1
522 >             jend = nGroups
523 > #endif
524 >          else            
525 >             jstart = point(i)
526 >             jend = point(i+1) - 1
527 >             ! make sure group i has neighbors
528 >             if (jstart .gt. jend) cycle outer
529 >          endif
530            
531 <          neighborListSize = size(list)
532 <          nlist = 0      
533 <          
534 <          do i = 1, nGroup-1
535 <             point(i) = nlist + 1
536 <            
537 <             do j = i+1, nGroup
538 <                
539 <                call get_interatomic_vector(q_group(:,i), &
540 <                     q_group(:,j), d_grp, rgrpsq)
541 <                
542 <                if (rgrpsq < rlistsq) then
531 >          do jnab = jstart, jend
532 >             if (update_nlist) then
533 >                j = jnab
534 >             else
535 >                j = list(jnab)
536 >             endif
537 >
538 > #ifdef IS_MPI
539 >             call get_interatomic_vector(q_group_Row(:,i), &
540 >                  q_group_Col(:,j), d_grp, rgrpsq)
541 > #else
542 >             call get_interatomic_vector(q_group(:,i), &
543 >                  q_group(:,j), d_grp, rgrpsq)
544 > #endif
545 >
546 >             if (rgrpsq < rlistsq) then
547 >                if (update_nlist) then
548                     nlist = nlist + 1
549                    
550                     if (nlist > neighborListSize) then
551 <                      call expandNeighborList(nGroup, listerror)
551 > #ifdef IS_MPI                
552 >                      call expandNeighborList(nGroupsInRow, listerror)
553 > #else
554 >                      call expandNeighborList(nGroups, listerror)
555 > #endif
556                        if (listerror /= 0) then
557                           error = -1
558                           write(DEFAULT_ERROR,*) "ERROR: nlist > list size and max allocations exceeded."
# Line 598 | Line 562 | contains
562                     endif
563                    
564                     list(nlist) = j
601                  
602                   do ia = groupStart(i), groupStart(i+1)-1
603                      atom1 = groupList(ia)
604                      
605                      prepair_inner: do jb = groupStart(j), groupStart(j+1)-1
606                         atom2 = groupList(jb)
607                        
608                         if (skipThisPair(atom1, atom2)) cycle prepair_inner
609                        
610                         call get_interatomic_vector(q(:,atom1), &
611                              q(:,atom2), d_atm, ratmsq)
612                        
613                         call do_prepair(atom1, atom2, ratmsq, d_atm, &
614                              rgrpsq, d_grp, do_pot, do_stress, &
615                              u_l, A, f, t, pot)
616                        
617                      enddo prepair_inner
618                   enddo
619                end if
620             enddo
621          enddo
622          point(nGroup) = nlist + 1          
623                          
624       else  !! (of update_check)
625          
626          ! use the list to find the neighbors
627          do i = 1, nGroup-1
628             JBEG = POINT(i)
629             JEND = POINT(i+1) - 1
630             ! check that group i has neighbors
631             if (jbeg .le. jend) then
632                
633                do jnab = jbeg, jend
634                   j = list(jnab)
635                  
636                   do ia = groupStart(i), groupStart(i+1)-1
637                      atom1 = groupList(ia)
638
639                      do jb = groupStart(j), groupStart(j+1)-1
640                         atom2 = groupList(jb)                        
641                        
642                         call get_interatomic_vector(q(:,atom1), &
643                              q(:,atom2), d_atm, ratmsq)
644                        
645                         call do_prepair(atom1, atom2, ratmsq, d_atm, &
646                              rgrpsq, d_grp, do_pot, do_stress, &
647                              u_l, A, f, t, pot)
648                        
649                      enddo
650                   enddo
651                enddo
652             endif
653          enddo
654       endif
655      
656 #endif
657      
658       !! Do rest of preforce calculations
659       !! do necessary preforce calculations  
660       call do_preforce(nlocal,pot)
661       ! we have already updated the neighbor list set it to false...
662       update_nlist = .false.
663    else
664       !! See if we need to update neighbor lists for non pre-pair
665       call checkNeighborList(nGroup, q_group, listSkin, update_nlist)  
666    endif
667    
668    !---------------------------------MAIN Pair LOOP->>>>>>>>>>>>>
669    
670 #ifdef IS_MPI
671    
672    if (update_nlist) then
673      
674       !! save current configuration, construct neighbor list,
675       !! and calculate forces
676      
677       call saveNeighborList(nGroup, q_group)
678      
679       neighborListSize = size(list)
680       nlist = 0      
681      
682       do i = 1, nrow_group
683          point(i) = nlist + 1
684          
685          do j = 1, ncol_group
686            
687             call get_interatomic_vector(q_group_Row(:,i), &
688                  q_group_Col(:,j), d_grp, rgrpsq)
689            
690             if (rgrpsq < rlistsq) then
691                nlist = nlist + 1
692                
693                if (nlist > neighborListSize) then
694                   call expandNeighborList(nGroup, listerror)
695                   if (listerror /= 0) then
696                      error = -1
697                      write(DEFAULT_ERROR,*) "ERROR: nlist > list size and max allocations exceeded."
698                      return
699                   end if
700                   neighborListSize = size(list)
565                  endif
566                  
567 <                list(nlist) = j
568 <                
569 <                vab = 0.0d0
706 <                call get_switch(rgrpsq, sw, dswdr, rgrp, group_switch, &
707 <                     in_switching_region)
708 <                
709 <                do ia = groupStart(i), groupStart(i+1)-1
710 <                   atom1 = groupList(ia)
711 <                  
712 <                   inner: do jb = groupStart(j), groupStart(j+1)-1
713 <                      atom2 = groupList(jb)
714 <                      
715 <                      if (skipThisPair(atom1, atom2)) cycle inner
716 <                      
717 <                      call get_interatomic_vector(q_Row(:,atom1), &
718 <                           q_Col(:,atom2), d_atm, ratmsq)
719 <                      
720 <                      call do_pair(atom1, atom2, ratmsq, d_atm, sw, &
721 <                           do_pot, do_stress, &
722 <                           u_l, A, f, t, pot_local, vpair)
723 <                      
724 <                      vab = vab + vpair
725 <                   enddo inner
726 <                enddo
727 <
728 <                if (in_switching_region) then
729 <                   swderiv = vab*dswdr/rgrp
730 <                  
731 <                   do ia=groupStart(i), groupStart(i+1)-1
732 <                      atom1=groupList(ia)
733 <                      mf = mfact(atom1)                  
734 <                      f_Row(1,atom1) = f_Row(1,atom1) - swderiv*d_grp(1)*mf
735 <                      f_Row(2,atom1) = f_Row(2,atom1) - swderiv*d_grp(2)*mf
736 <                      f_Row(3,atom1) = f_Row(3,atom1) - swderiv*d_grp(3)*mf
737 <                   enddo
738 <                  
739 <                   do jb=groupStart(j), groupStart(j+1)-1
740 <                      atom2=groupList(jb)
741 <                      mf = mfact(atom2)
742 <                      f_Col(1,atom2) = f_Col(1,atom2) + swderiv*d_grp(1)*mf
743 <                      f_Col(2,atom2) = f_Col(2,atom2) + swderiv*d_grp(2)*mf
744 <                      f_Col(3,atom2) = f_Col(3,atom2) + swderiv*d_grp(3)*mf
745 <                   enddo                        
567 >                if (loop .eq. PAIR_LOOP) then
568 >                   vij = 0.0d0
569 >                   fij(1:3) = 0.0d0
570                  endif
747
748             end if
749          enddo
750       enddo
751       point(nrow_group + 1) = nlist + 1          
752      
753    else  !! (of update_check)
754      
755       ! use the list to find the neighbors
756       do i = 1, nrow_group
757          JBEG = POINT(i)
758          JEND = POINT(i+1) - 1
759          ! check that group i has neighbors
760          if (jbeg .le. jend) then
761            
762             do jnab = jbeg, jend
763                j = list(jnab)
764                              
765                call get_interatomic_vector(q_group_Row(:,i), &
766                     q_group_Col(:,j), d_grp, rgrpsq)
571                  
768                vab = 0.0d0
572                  call get_switch(rgrpsq, sw, dswdr, rgrp, group_switch, &
573                       in_switching_region)
574                  
575 <                do ia = groupStart(i), groupStart(i+1)-1
576 <                   atom1 = groupList(ia)
575 >                n_in_j = groupStartCol(j+1) - groupStartCol(j)
576 >                
577 >                do ia = groupStartRow(i), groupStartRow(i+1)-1
578                    
579 <                   do jb = groupStart(j), groupStart(j+1)-1
580 <                      atom2 = groupList(jb)                        
579 >                   atom1 = groupListRow(ia)
580 >                  
581 >                   inner: do jb = groupStartCol(j), groupStartCol(j+1)-1
582                        
583 <                      call get_interatomic_vector(q_Row(:,atom1), &
779 <                           q_Col(:,atom2), d_atm, ratmsq)
780 <                                            
781 <                      call do_pair(atom1, atom2, ratmsq, d_atm, sw, &
782 <                           do_pot, do_stress, &
783 <                           u_l, A, f, t, pot_local, vpair)
583 >                      atom2 = groupListCol(jb)
584                        
585 <                      vab = vab + vpair
786 <                                            
787 <                   enddo
788 <                enddo
789 <                
790 <                if (in_switching_region) then
791 <                   swderiv = vab*dswdr/rgrp
792 <  
793 <                   do ia=groupStart(i), groupStart(i+1)-1
794 <                      atom1=groupList(ia)
795 <                      mf = mfact(atom1)                  
796 <                      f_Row(1,atom1) = f_Row(1,atom1) - swderiv*d_grp(1)*mf
797 <                      f_Row(2,atom1) = f_Row(2,atom1) - swderiv*d_grp(2)*mf
798 <                      f_Row(3,atom1) = f_Row(3,atom1) - swderiv*d_grp(3)*mf
799 <                   enddo
800 <                  
801 <                   do jb=groupStart(j), groupStart(j+1)-1
802 <                      atom2=groupList(jb)
803 <                      mf = mfact(atom2)
804 <                      f_Col(1,atom2) = f_Col(1,atom2) + swderiv*d_grp(1)*mf
805 <                      f_Col(2,atom2) = f_Col(2,atom2) + swderiv*d_grp(2)*mf
806 <                      f_Col(3,atom2) = f_Col(3,atom2) + swderiv*d_grp(3)*mf
807 <                   enddo
808 <                endif
585 >                      if (skipThisPair(atom1, atom2)) cycle inner
586  
587 <             enddo
588 <          endif
589 <       enddo
590 <    endif
591 <    
587 >                      if ((n_in_i .eq. 1).and.(n_in_j .eq. 1)) then
588 >                         d_atm(1:3) = d_grp(1:3)
589 >                         ratmsq = rgrpsq
590 >                      else
591 > #ifdef IS_MPI
592 >                         call get_interatomic_vector(q_Row(:,atom1), &
593 >                              q_Col(:,atom2), d_atm, ratmsq)
594   #else
595 +                         call get_interatomic_vector(q(:,atom1), &
596 +                              q(:,atom2), d_atm, ratmsq)
597 + #endif
598 +                      endif
599  
600 <    if (update_nlist) then
601 <      
602 <       !! save current configuration, construct neighbor list,
603 <       !! and calculate forces
604 <      
605 <       call saveNeighborList(nGroup, q_group)
606 <      
607 <       neighborListSize = size(list)
608 <       nlist = 0      
609 <      
610 <       do i = 1, nGroup-1
611 <          point(i) = nlist + 1
612 <          
613 <          do j = i+1, nGroup
614 <            
615 <             call get_interatomic_vector(q_group(:,i), &
616 <                  q_group(:,j), d_grp, rgrpsq)
617 <            
618 <             if (rgrpsq < rlistsq) then
619 <                nlist = nlist + 1
837 <                
838 <                if (nlist > neighborListSize) then
839 <                   call expandNeighborList(nGroup, listerror)
840 <                   if (listerror /= 0) then
841 <                      error = -1
842 <                      write(DEFAULT_ERROR,*) "ERROR: nlist > list size and max allocations exceeded."
843 <                      return
844 <                   end if
845 <                   neighborListSize = size(list)
846 <                endif
847 <                
848 <                list(nlist) = j
600 >                      if (loop .eq. PREPAIR_LOOP) then
601 > #ifdef IS_MPI                      
602 >                         call do_prepair(atom1, atom2, ratmsq, d_atm, sw, &
603 >                              rgrpsq, d_grp, do_pot, do_stress, &
604 >                              u_l, A, f, t, pot_local)
605 > #else
606 >                         call do_prepair(atom1, atom2, ratmsq, d_atm, sw, &
607 >                              rgrpsq, d_grp, do_pot, do_stress, &
608 >                              u_l, A, f, t, pot)
609 > #endif                                              
610 >                      else
611 > #ifdef IS_MPI                      
612 >                         call do_pair(atom1, atom2, ratmsq, d_atm, sw, &
613 >                              do_pot, &
614 >                              u_l, A, f, t, pot_local, vpair, fpair)
615 > #else
616 >                         call do_pair(atom1, atom2, ratmsq, d_atm, sw, &
617 >                              do_pot,  &
618 >                              u_l, A, f, t, pot, vpair, fpair)
619 > #endif
620  
621 <                vab = 0.0d0
622 <                call get_switch(rgrpsq, sw, dswdr, rgrp, group_switch, &
623 <                     in_switching_region)
621 >                         vij = vij + vpair
622 >                         fij(1:3) = fij(1:3) + fpair(1:3)
623 >                      endif
624 >                   enddo inner
625 >                enddo
626                  
627 <                do ia = groupStart(i), groupStart(i+1)-1
628 <                   atom1 = groupList(ia)
629 <                  
630 <                   inner: do jb = groupStart(j), groupStart(j+1)-1
631 <                      atom2 = groupList(jb)
627 >                if (loop .eq. PAIR_LOOP) then
628 >                   if (in_switching_region) then
629 >                      swderiv = vij*dswdr/rgrp
630 >                      fij(1) = fij(1) + swderiv*d_grp(1)
631 >                      fij(2) = fij(2) + swderiv*d_grp(2)
632 >                      fij(3) = fij(3) + swderiv*d_grp(3)
633                        
634 <                      if (skipThisPair(atom1, atom2)) cycle inner
634 >                      do ia=groupStartRow(i), groupStartRow(i+1)-1
635 >                         atom1=groupListRow(ia)
636 >                         mf = mfactRow(atom1)
637 > #ifdef IS_MPI
638 >                         f_Row(1,atom1) = f_Row(1,atom1) + swderiv*d_grp(1)*mf
639 >                         f_Row(2,atom1) = f_Row(2,atom1) + swderiv*d_grp(2)*mf
640 >                         f_Row(3,atom1) = f_Row(3,atom1) + swderiv*d_grp(3)*mf
641 > #else
642 >                         f(1,atom1) = f(1,atom1) + swderiv*d_grp(1)*mf
643 >                         f(2,atom1) = f(2,atom1) + swderiv*d_grp(2)*mf
644 >                         f(3,atom1) = f(3,atom1) + swderiv*d_grp(3)*mf
645 > #endif
646 >                      enddo
647                        
648 <                      call get_interatomic_vector(q(:,atom1), &
649 <                           q(:,atom2), d_atm, ratmsq)
650 <                      
651 <                      call do_pair(atom1, atom2, ratmsq, d_atm, sw, &
652 <                           do_pot, do_stress, &
653 <                           u_l, A, f, t, pot, vpair)
654 <                      
655 <                      vab = vab + vpair
656 <                      
657 <                   enddo inner
658 <                enddo
659 <
660 <                if (in_switching_region) then
661 <                   swderiv = vab*dswdr/rgrp
876 <                   do ia=groupStart(i), groupStart(i+1)-1
877 <                      atom1=groupList(ia)
878 <                      mf = mfact(atom1)                  
879 <                      f(1,atom1) = f(1,atom1) - swderiv*d_grp(1)*mf
880 <                      f(2,atom1) = f(2,atom1) - swderiv*d_grp(2)*mf
881 <                      f(3,atom1) = f(3,atom1) - swderiv*d_grp(3)*mf
882 <                   enddo
648 >                      do jb=groupStartCol(j), groupStartCol(j+1)-1
649 >                         atom2=groupListCol(jb)
650 >                         mf = mfactCol(atom2)
651 > #ifdef IS_MPI
652 >                         f_Col(1,atom2) = f_Col(1,atom2) - swderiv*d_grp(1)*mf
653 >                         f_Col(2,atom2) = f_Col(2,atom2) - swderiv*d_grp(2)*mf
654 >                         f_Col(3,atom2) = f_Col(3,atom2) - swderiv*d_grp(3)*mf
655 > #else
656 >                         f(1,atom2) = f(1,atom2) - swderiv*d_grp(1)*mf
657 >                         f(2,atom2) = f(2,atom2) - swderiv*d_grp(2)*mf
658 >                         f(3,atom2) = f(3,atom2) - swderiv*d_grp(3)*mf
659 > #endif
660 >                      enddo
661 >                   endif
662                    
663 <                   do jb=groupStart(j), groupStart(j+1)-1
885 <                      atom2=groupList(jb)
886 <                      mf = mfact(atom2)
887 <                      f(1,atom2) = f(1,atom2) + swderiv*d_grp(1)*mf
888 <                      f(2,atom2) = f(2,atom2) + swderiv*d_grp(2)*mf
889 <                      f(3,atom2) = f(3,atom2) + swderiv*d_grp(3)*mf
890 <                   enddo
663 >                   if (do_stress) call add_stress_tensor(d_grp, fij)
664                  endif
892
665               end if
666            enddo
667 <       enddo
896 <       point(nGroup) = nlist + 1          
667 >       enddo outer
668        
669 <    else  !! (of update_check)
670 <      
671 <       ! use the list to find the neighbors
672 <       do i = 1, nGroup-1
673 <          JBEG = POINT(i)
674 <          JEND = POINT(i+1) - 1
675 <          ! check that group i has neighbors
676 <          if (jbeg .le. jend) then
669 >       if (update_nlist) then
670 > #ifdef IS_MPI
671 >          point(nGroupsInRow + 1) = nlist + 1
672 > #else
673 >          point(nGroups) = nlist + 1
674 > #endif
675 >          if (loop .eq. PREPAIR_LOOP) then
676 >             ! we just did the neighbor list update on the first
677 >             ! pass, so we don't need to do it
678 >             ! again on the second pass
679 >             update_nlist = .false.                              
680 >          endif
681 >       endif
682              
683 <             do jnab = jbeg, jend
684 <                j = list(jnab)
685 <
686 <                call get_interatomic_vector(q_group(:,i), &
687 <                     q_group(:,j), d_grp, rgrpsq)
912 <
913 <                vab = 0.0d0                    
914 <                call get_switch(rgrpsq, sw, dswdr, rgrp, group_switch, &
915 <                     in_switching_region)
916 <                                
917 <                do ia = groupStart(i), groupStart(i+1)-1
918 <                   atom1 = groupList(ia)
919 <                  
920 <                   do jb = groupStart(j), groupStart(j+1)-1
921 <                      atom2 = groupList(jb)                        
922 <                      
923 <                      call get_interatomic_vector(q(:,atom1), &
924 <                           q(:,atom2), d_atm, ratmsq)
925 <                      
926 <                      call do_pair(atom1, atom2, ratmsq, d_atm, sw, &
927 <                           do_pot, do_stress, &
928 <                           u_l, A, f, t, pot, vpair)
929 <                      
930 <                      vab = vab + vpair
931 <                      
932 <                   enddo
933 <                enddo
934 <                
935 <                if (in_switching_region) then
936 <                   swderiv = vab*dswdr/rgrp
937 <                  
938 <                   do ia=groupStart(i), groupStart(i+1)-1
939 <                      atom1=groupList(ia)
940 <                      mf = mfact(atom1)                  
941 <                      f(1,atom1) = f(1,atom1) - swderiv*d_grp(1)*mf
942 <                      f(2,atom1) = f(2,atom1) - swderiv*d_grp(2)*mf
943 <                      f(3,atom1) = f(3,atom1) - swderiv*d_grp(3)*mf
944 <                   enddo
945 <                  
946 <                   do jb=groupStart(j), groupStart(j+1)-1
947 <                      atom2=groupList(jb)
948 <                      mf = mfact(atom2)
949 <                      f(1,atom2) = f(1,atom2) + swderiv*d_grp(1)*mf
950 <                      f(2,atom2) = f(2,atom2) + swderiv*d_grp(2)*mf
951 <                      f(3,atom2) = f(3,atom2) + swderiv*d_grp(3)*mf
952 <                   enddo
953 <                endif
954 <             enddo
955 <          endif
956 <       enddo
957 <    endif
958 <        
959 < #endif
683 >       if (loop .eq. PREPAIR_LOOP) then
684 >          call do_preforce(nlocal, pot)
685 >       endif
686 >      
687 >    enddo
688      
961    ! phew, done with main loop.
962    
689      !! Do timing
690   #ifdef PROFILE
691      call cpu_time(forceTimeFinal)
# Line 970 | Line 696 | contains
696      !!distribute forces
697      
698      f_temp = 0.0_dp
699 <    call scatter(f_Row,f_temp,plan_row3d)
699 >    call scatter(f_Row,f_temp,plan_atom_row_3d)
700      do i = 1,nlocal
701         f(1:3,i) = f(1:3,i) + f_temp(1:3,i)
702      end do
703      
704      f_temp = 0.0_dp
705 <    call scatter(f_Col,f_temp,plan_col3d)
705 >    call scatter(f_Col,f_temp,plan_atom_col_3d)
706      do i = 1,nlocal
707         f(1:3,i) = f(1:3,i) + f_temp(1:3,i)
708      end do
709      
710      if (FF_UsesDirectionalAtoms() .and. SIM_uses_directional_atoms) then
711         t_temp = 0.0_dp
712 <       call scatter(t_Row,t_temp,plan_row3d)
712 >       call scatter(t_Row,t_temp,plan_atom_row_3d)
713         do i = 1,nlocal
714            t(1:3,i) = t(1:3,i) + t_temp(1:3,i)
715         end do
716         t_temp = 0.0_dp
717 <       call scatter(t_Col,t_temp,plan_col3d)
717 >       call scatter(t_Col,t_temp,plan_atom_col_3d)
718        
719         do i = 1,nlocal
720            t(1:3,i) = t(1:3,i) + t_temp(1:3,i)
# Line 997 | Line 723 | contains
723      
724      if (do_pot) then
725         ! scatter/gather pot_row into the members of my column
726 <       call scatter(pot_Row, pot_Temp, plan_row)
726 >       call scatter(pot_Row, pot_Temp, plan_atom_row)
727        
728         ! scatter/gather pot_local into all other procs
729         ! add resultant to get total pot
# Line 1007 | Line 733 | contains
733        
734         pot_Temp = 0.0_DP
735        
736 <       call scatter(pot_Col, pot_Temp, plan_col)
736 >       call scatter(pot_Col, pot_Temp, plan_atom_col)
737         do i = 1, nlocal
738            pot_local = pot_local + pot_Temp(i)
739         enddo
# Line 1020 | Line 746 | contains
746         if (FF_uses_RF .and. SIM_uses_RF) then
747            
748   #ifdef IS_MPI
749 <          call scatter(rf_Row,rf,plan_row3d)
750 <          call scatter(rf_Col,rf_Temp,plan_col3d)
749 >          call scatter(rf_Row,rf,plan_atom_row_3d)
750 >          call scatter(rf_Col,rf_Temp,plan_atom_col_3d)
751            do i = 1,nlocal
752               rf(1:3,i) = rf(1:3,i) + rf_Temp(1:3,i)
753            end do
# Line 1081 | Line 807 | contains
807      endif
808      
809   #endif
810 <    
1085 <    
810 >      
811    end subroutine do_force_loop
1087
812    
813 <  subroutine do_pair(i, j, rijsq, d, sw, do_pot, do_stress, &
814 <       u_l, A, f, t, pot, vpair)
813 >  subroutine do_pair(i, j, rijsq, d, sw, do_pot, &
814 >       u_l, A, f, t, pot, vpair, fpair)
815  
816      real( kind = dp ) :: pot, vpair, sw
817 +    real( kind = dp ), dimension(3) :: fpair
818      real( kind = dp ), dimension(nLocal)   :: mfact
819      real( kind = dp ), dimension(3,nLocal) :: u_l
820      real( kind = dp ), dimension(9,nLocal) :: A
821      real( kind = dp ), dimension(3,nLocal) :: f
822      real( kind = dp ), dimension(3,nLocal) :: t
823  
824 <    logical, intent(inout) :: do_pot, do_stress
824 >    logical, intent(inout) :: do_pot
825      integer, intent(in) :: i, j
826      real ( kind = dp ), intent(inout) :: rijsq
827      real ( kind = dp )                :: r
# Line 1104 | Line 829 | contains
829      integer :: me_i, me_j
830  
831      r = sqrt(rijsq)
832 +    vpair = 0.0d0
833 +    fpair(1:3) = 0.0d0
834  
835   #ifdef IS_MPI
1109    if (tagRow(i) .eq. tagColumn(j)) then
1110       write(0,*) 'do_pair is doing', i , j, tagRow(i), tagColumn(j)
1111    endif
836      me_i = atid_row(i)
837      me_j = atid_col(j)
838   #else
# Line 1119 | Line 843 | contains
843      if (FF_uses_LJ .and. SIM_uses_LJ) then
844        
845         if ( PropertyMap(me_i)%is_LJ .and. PropertyMap(me_j)%is_LJ ) then
846 <          call do_lj_pair(i, j, d, r, rijsq, sw, vpair, pot, f, do_pot, &
1123 <               do_stress)
846 >          call do_lj_pair(i, j, d, r, rijsq, sw, vpair, fpair, pot, f, do_pot)
847         endif
848        
849      endif
# Line 1128 | Line 851 | contains
851      if (FF_uses_charges .and. SIM_uses_charges) then
852        
853         if (PropertyMap(me_i)%is_Charge .and. PropertyMap(me_j)%is_Charge) then
854 <          call do_charge_pair(i, j, d, r, rijsq, sw, vpair, pot, f, do_pot, &
1132 <               do_stress)
854 >          call do_charge_pair(i, j, d, r, rijsq, sw, vpair, fpair, pot, f, do_pot)
855         endif
856        
857      endif
# Line 1137 | Line 859 | contains
859      if (FF_uses_dipoles .and. SIM_uses_dipoles) then
860        
861         if ( PropertyMap(me_i)%is_DP .and. PropertyMap(me_j)%is_DP) then
862 <          call do_dipole_pair(i, j, d, r, rijsq, sw, vpair, pot, u_l, f, t, &
863 <               do_pot, do_stress)
862 >          call do_dipole_pair(i, j, d, r, rijsq, sw, vpair, fpair, pot, u_l, f, t, &
863 >               do_pot)
864            if (FF_uses_RF .and. SIM_uses_RF) then
865               call accumulate_rf(i, j, r, u_l, sw)
866 <             call rf_correct_forces(i, j, d, r, u_l, sw, f, do_stress)
866 >             call rf_correct_forces(i, j, d, r, u_l, sw, f, fpair)
867            endif          
868         endif
869  
# Line 1150 | Line 872 | contains
872      if (FF_uses_Sticky .and. SIM_uses_sticky) then
873  
874         if ( PropertyMap(me_i)%is_Sticky .and. PropertyMap(me_j)%is_Sticky) then
875 <          call do_sticky_pair(i, j, d, r, rijsq, sw, vpair, pot, A, f, t, &
876 <               do_pot, do_stress)
875 >          call do_sticky_pair(i, j, d, r, rijsq, sw, vpair, fpair, pot, A, f, t, &
876 >               do_pot)
877         endif
878  
879      endif
# Line 1160 | Line 882 | contains
882      if (FF_uses_GB .and. SIM_uses_GB) then
883        
884         if ( PropertyMap(me_i)%is_GB .and. PropertyMap(me_j)%is_GB) then
885 <          call do_gb_pair(i, j, d, r, rijsq, sw, vpair, pot, u_l, f, t, &
886 <               do_pot, do_stress)          
885 >          call do_gb_pair(i, j, d, r, rijsq, sw, vpair, fpair, pot, u_l, f, t, &
886 >               do_pot)
887         endif
888  
889      endif
# Line 1169 | Line 891 | contains
891      if (FF_uses_EAM .and. SIM_uses_EAM) then
892        
893         if ( PropertyMap(me_i)%is_EAM .and. PropertyMap(me_j)%is_EAM) then
894 <          call do_eam_pair(i, j, d, r, rijsq, sw, vpair, pot, f, &
895 <               do_pot, do_stress)
894 >          call do_eam_pair(i, j, d, r, rijsq, sw, vpair, fpair, pot, f, &
895 >               do_pot)
896         endif
897        
898      endif
899      
900    end subroutine do_pair
901  
902 <  subroutine do_prepair(i, j, rijsq, d, rcijsq, dc, &
902 >  subroutine do_prepair(i, j, rijsq, d, sw, rcijsq, dc, &
903         do_pot, do_stress, u_l, A, f, t, pot)
904 <   real( kind = dp ) :: pot
904 >
905 >   real( kind = dp ) :: pot, sw
906     real( kind = dp ), dimension(3,nLocal) :: u_l
907     real (kind=dp), dimension(9,nLocal) :: A
908     real (kind=dp), dimension(3,nLocal) :: f
# Line 1204 | Line 927 | contains
927      endif
928    
929  
930 < #ifdef IS_MPI
1208 <   if (tagRow(i) .eq. tagColumn(j)) then
1209 <      write(0,*) 'do_pair is doing', i , j, tagRow(i), tagColumn(j)
1210 <   endif
1211 <  
930 > #ifdef IS_MPI  
931     me_i = atid_row(i)
932 <   me_j = atid_col(j)
933 <  
1215 < #else
1216 <  
932 >   me_j = atid_col(j)  
933 > #else  
934     me_i = atid(i)
935 <   me_j = atid(j)
1219 <  
935 >   me_j = atid(j)  
936   #endif
937 <    
937 >  
938     if (FF_uses_EAM .and. SIM_uses_EAM) then
939 <
939 >      
940        if (PropertyMap(me_i)%is_EAM .and. PropertyMap(me_j)%is_EAM) &
941             call calc_EAM_prepair_rho(i, j, d, r, rijsq )
942 <
942 >      
943     endif
944    
945   end subroutine do_prepair
946 <
947 <
1232 <
1233 <
946 >
947 >
948   subroutine do_preforce(nlocal,pot)
949     integer :: nlocal
950     real( kind = dp ) :: pot
# Line 1355 | Line 1069 | contains
1069    
1070   #ifdef IS_MPI
1071     !! in MPI, we have to look up the unique IDs for each atom
1072 <   unique_id_1 = tagRow(atom1)
1072 >   unique_id_1 = AtomRowToGlobal(atom1)
1073   #else
1074     !! in the normal loop, the atom numbers are unique
1075     unique_id_1 = atom1
# Line 1374 | Line 1088 | contains
1088     end if
1089    
1090   #ifdef IS_MPI
1091 <   unique_id_2 = tagColumn(atom2)
1091 >   unique_id_2 = AtomColToGlobal(atom2)
1092   #else
1093     unique_id_2 = atom2
1094   #endif
# Line 1409 | Line 1123 | contains
1123        endif
1124     enddo
1125    
1126 <   do i = 1, nExcludes_local
1127 <      if (excludesLocal(1,i) == unique_id_1) then
1128 <         if (excludesLocal(2,i) == unique_id_2) then
1129 <            skip_it = .true.
1416 <            return
1417 <         endif
1418 <      else
1419 <         if (excludesLocal(1,i) == unique_id_2) then
1420 <            if (excludesLocal(2,i) == unique_id_1) then
1421 <               skip_it = .true.
1422 <               return
1423 <            endif
1424 <         endif
1126 >   do i = 1, nSkipsForAtom(atom1)
1127 >      if (skipsForAtom(atom1, i) .eq. unique_id_2) then
1128 >         skip_it = .true.
1129 >         return
1130        endif
1131     end do
1132    
# Line 1452 | Line 1157 | contains
1157   #endif
1158  
1159   !! This cleans componets of force arrays belonging only to fortran
1160 +
1161 + subroutine add_stress_tensor(dpair, fpair)
1162 +  
1163 +   real( kind = dp ), dimension(3), intent(in) :: dpair, fpair
1164 +  
1165 +   ! because the d vector is the rj - ri vector, and
1166 +   ! because fx, fy, fz are the force on atom i, we need a
1167 +   ! negative sign here:  
1168 +  
1169 +   tau_Temp(1) = tau_Temp(1) - dpair(1) * fpair(1)
1170 +   tau_Temp(2) = tau_Temp(2) - dpair(1) * fpair(2)
1171 +   tau_Temp(3) = tau_Temp(3) - dpair(1) * fpair(3)
1172 +   tau_Temp(4) = tau_Temp(4) - dpair(2) * fpair(1)
1173 +   tau_Temp(5) = tau_Temp(5) - dpair(2) * fpair(2)
1174 +   tau_Temp(6) = tau_Temp(6) - dpair(2) * fpair(3)
1175 +   tau_Temp(7) = tau_Temp(7) - dpair(3) * fpair(1)
1176 +   tau_Temp(8) = tau_Temp(8) - dpair(3) * fpair(2)
1177 +   tau_Temp(9) = tau_Temp(9) - dpair(3) * fpair(3)
1178 +  
1179 +   virial_Temp = virial_Temp + &
1180 +        (tau_Temp(1) + tau_Temp(5) + tau_Temp(9))
1181 +  
1182 + end subroutine add_stress_tensor
1183  
1184   end module do_Forces
1185 +

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines