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 1183 by gezelter, Fri May 21 15:58:48 2004 UTC vs.
Revision 1199 by gezelter, Thu May 27 15:21:20 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.60 2004-05-21 15:58:40 gezelter Exp $, $Date: 2004-05-21 15:58:40 $, $Name: not supported by cvs2svn $, $Revision: 1.60 $
7 > !! @version $Id: do_Forces.F90,v 1.64 2004-05-27 15:21:20 gezelter Exp $, $Date: 2004-05-27 15:21:20 $, $Name: not supported by cvs2svn $, $Revision: 1.64 $
8  
9   module do_Forces
10    use force_globals
# Line 32 | Line 32 | module do_Forces
32   #define __FORTRAN90
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.
# Line 372 | Line 375 | contains
375      !! Position array provided by C, dimensioned by getNlocal
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    
381      !! Unit vectors for dipoles (lab frame)
# 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, 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, n_in_i, n_in_j
414      logical :: is_dp_i
# Line 412 | Line 416 | contains
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
474 >       loopStart = PREPAIR_LOOP
475 >    else
476 >       loopStart = PAIR_LOOP
477 >    endif
478  
479 <       call checkNeighborList(nGroup, q_group, listSkin, update_nlist)
479 >    do loop = loopStart, loopEnd
480  
481 <       !! if_mpi_gather_stuff_for_prepair
482 <       !! do_prepair_loop_if_needed
483 <       !! if_mpi_scatter_stuff_from_prepair
484 <       !! if_mpi_gather_stuff_from_prepair_to_main_loop
481 >       ! See if we need to update neighbor lists
482 >       ! (but only on the first time through):
483 >       if (loop .eq. loopStart) then
484 >          call checkNeighborList(nGroups, q_group, listSkin, update_nlist)
485 >       endif
486        
477       !--------------------PREFORCE LOOP----------->>>>>>>>>>>>>>>>>>>>>>>>>>>
478 #ifdef IS_MPI
479      
487         if (update_nlist) then
488 <          
489 <          !! save current configuration, construct neighbor list,
490 <          !! and calculate forces
491 <
492 <          call saveNeighborList(nGroup, q_group)
493 <          
488 >          !! save current configuration and construct neighbor list
489 > #ifdef IS_MPI
490 >          call saveNeighborList(nGroupsInRow, q_group)
491 > #else
492 >          call saveNeighborList(nGroups, q_group)
493 > #endif        
494            neighborListSize = size(list)
495 <          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_inner1: do jb = groupStart(j), groupStart(j+1)-1
517 <                         atom2 = groupList(jb)
518 <                        
519 <                         if (skipThisPair(atom1, atom2)) cycle prepair_inner1
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_inner1
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 <                      prepair_inner2: do jb = groupStart(j), groupStart(j+1)-1
551 <                         atom2 = groupList(jb)                        
552 <                        
553 <                         if (skipThisPair(atom1, atom2)) cycle prepair_inner2
554 <
555 <                         call get_interatomic_vector(q_Row(:,atom1), &
556 <                              q_Col(:,atom2), d_atm, ratmsq)
557 <                        
558 <                         call do_prepair(atom1, atom2, ratmsq, d_atm, &
559 <                              rgrpsq, d_grp, do_pot, do_stress, &
560 <                              u_l, A, f, t, pot_local)
561 <                        
562 <                      enddo prepair_inner2
563 <                   enddo
564 <                enddo
565 <             endif
566 <          enddo
495 >          nlist = 0
496         endif
497        
498 +       istart = 1
499 + #ifdef IS_MPI
500 +       iend = nGroupsInRow
501   #else
502 <
503 <       if (update_nlist) then
502 >       iend = nGroups - 1
503 > #endif
504 >       outer: do i = istart, iend
505            
506 <          !! save current configuration, construct neighbor list,
574 <          !! and calculate forces
506 >          if (update_nlist) point(i) = nlist + 1
507            
508 <          call saveNeighborList(nGroup, q_group)
508 >          n_in_i = groupStartRow(i+1) - groupStartRow(i)
509            
510 <          neighborListSize = size(list)
511 <          nlist = 0      
510 >          if (update_nlist) then
511 > #ifdef IS_MPI
512 >             jstart = 1
513 >             jend = nGroupsInCol
514 > #else
515 >             jstart = i+1
516 >             jend = nGroups
517 > #endif
518 >          else            
519 >             jstart = point(i)
520 >             jend = point(i+1) - 1
521 >             ! make sure group i has neighbors
522 >             if (jstart .gt. jend) cycle outer
523 >          endif
524            
525 <          do i = 1, nGroup-1
526 <             point(i) = nlist + 1
527 <            
528 <             do j = i+1, nGroup
529 <                
530 <                call get_interatomic_vector(q_group(:,i), &
531 <                     q_group(:,j), d_grp, rgrpsq)
532 <                
533 <                if (rgrpsq < rlistsq) then
525 >          do jnab = jstart, jend
526 >             if (update_nlist) then
527 >                j = jnab
528 >             else
529 >                j = list(jnab)
530 >             endif
531 >
532 > #ifdef IS_MPI
533 >             call get_interatomic_vector(q_group_Row(:,i), &
534 >                  q_group_Col(:,j), d_grp, rgrpsq)
535 > #else
536 >             call get_interatomic_vector(q_group(:,i), &
537 >                  q_group(:,j), d_grp, rgrpsq)
538 > #endif
539 >
540 >             if (rgrpsq < rlistsq) then
541 >                if (update_nlist) then
542                     nlist = nlist + 1
543                    
544                     if (nlist > neighborListSize) then
545 <                      call expandNeighborList(nGroup, listerror)
545 > #ifdef IS_MPI                
546 >                      call expandNeighborList(nGroupsInRow, listerror)
547 > #else
548 >                      call expandNeighborList(nGroups, listerror)
549 > #endif
550                        if (listerror /= 0) then
551                           error = -1
552                           write(DEFAULT_ERROR,*) "ERROR: nlist > list size and max allocations exceeded."
# Line 600 | Line 556 | contains
556                     endif
557                    
558                     list(nlist) = j
603                  
604                   do ia = groupStart(i), groupStart(i+1)-1
605                      atom1 = groupList(ia)
606                      
607                      prepair_inner1: do jb = groupStart(j), groupStart(j+1)-1
608                         atom2 = groupList(jb)
609                        
610                         if (skipThisPair(atom1, atom2)) cycle prepair_inner1
611                        
612                         call get_interatomic_vector(q(:,atom1), &
613                              q(:,atom2), d_atm, ratmsq)
614                        
615                         call do_prepair(atom1, atom2, ratmsq, d_atm, &
616                              rgrpsq, d_grp, do_pot, do_stress, &
617                              u_l, A, f, t, pot)
618                        
619                      enddo prepair_inner1
620                   enddo
621                end if
622             enddo
623          enddo
624          point(nGroup) = nlist + 1          
625                          
626       else  !! (of update_check)
627          
628          ! use the list to find the neighbors
629          do i = 1, nGroup-1
630             JBEG = POINT(i)
631             JEND = POINT(i+1) - 1
632             ! check that group i has neighbors
633             if (jbeg .le. jend) then
634                
635                do jnab = jbeg, jend
636                   j = list(jnab)
637                  
638                   do ia = groupStart(i), groupStart(i+1)-1
639                      atom1 = groupList(ia)
640
641                      prepair_inner2: do jb = groupStart(j), groupStart(j+1)-1
642                         atom2 = groupList(jb)                        
643                        
644                         if (skipThisPair(atom1, atom2)) cycle prepair_inner2
645
646                         call get_interatomic_vector(q(:,atom1), &
647                              q(:,atom2), d_atm, ratmsq)
648                        
649                         call do_prepair(atom1, atom2, ratmsq, d_atm, &
650                              rgrpsq, d_grp, do_pot, do_stress, &
651                              u_l, A, f, t, pot)
652                        
653                      enddo prepair_inner2
654                   enddo
655                enddo
656             endif
657          enddo
658       endif
659      
660 #endif
661      
662       !! Do rest of preforce calculations
663       !! do necessary preforce calculations  
664       call do_preforce(nlocal,pot)
665       ! we have already updated the neighbor list set it to false...
666       update_nlist = .false.
667    else
668       !! See if we need to update neighbor lists for non pre-pair
669       call checkNeighborList(nGroup, q_group, listSkin, update_nlist)  
670    endif
671    
672    !---------------------------------MAIN Pair LOOP->>>>>>>>>>>>>
673    
674 #ifdef IS_MPI
675    
676    if (update_nlist) then
677      
678       !! save current configuration, construct neighbor list,
679       !! and calculate forces
680      
681       call saveNeighborList(nGroup, q_group)
682      
683       neighborListSize = size(list)
684       nlist = 0      
685      
686       do i = 1, nrow_group
687
688          point(i) = nlist + 1
689
690          n_in_i = groupStart(i+1) - groupStart(i)
691          
692          do j = 1, ncol_group
693            
694             call get_interatomic_vector(q_group_Row(:,i), &
695                  q_group_Col(:,j), d_grp, rgrpsq)
696            
697             if (rgrpsq < rlistsq) then
698                nlist = nlist + 1
699                
700                if (nlist > neighborListSize) then
701                   call expandNeighborList(nGroup, listerror)
702                   if (listerror /= 0) then
703                      error = -1
704                      write(DEFAULT_ERROR,*) "ERROR: nlist > list size and max allocations exceeded."
705                      return
706                   end if
707                   neighborListSize = size(list)
559                  endif
560                  
561 <                list(nlist) = j
562 <                
563 <                vij = 0.0d0
713 <
714 <                call get_switch(rgrpsq, sw, dswdr, rgrp, group_switch, &
715 <                     in_switching_region)
716 <
717 <                n_in_j = groupStart(j+1) - groupStart(j)
718 <                
719 <                do ia = groupStart(i), groupStart(i+1)-1
720 <                   atom1 = groupList(ia)
721 <                  
722 <                   inner1: do jb = groupStart(j), groupStart(j+1)-1
723 <                      atom2 = groupList(jb)                    
724 <
725 <                      if (skipThisPair(atom1, atom2)) cycle inner1
726 <                      
727 <                      if ((n_in_i .eq. 1).and.(n_in_j .eq. 1)) then
728 <                         d_atm(1:3) = d_grp(1:3)
729 <                         ratmsq = rgrpsq
730 <                      else
731 <                         call get_interatomic_vector(q_Row(:,atom1), &
732 <                              q_Col(:,atom2), d_atm, ratmsq)
733 <                      endif
734 <                      
735 <                      call do_pair(atom1, atom2, ratmsq, d_atm, sw, &
736 <                           do_pot, do_stress, &
737 <                           u_l, A, f, t, pot_local, vpair)
738 <                      
739 <                      vij = vij + vpair
740 <                   enddo inner1
741 <                enddo
742 <
743 <                if (in_switching_region) then
744 <                   swderiv = vij*dswdr/rgrp
745 <                  
746 <                   do ia=groupStart(i), groupStart(i+1)-1
747 <                      atom1=groupList(ia)
748 <                      mf = mfact(atom1)                  
749 <                      f_Row(1,atom1) = f_Row(1,atom1) + swderiv*d_grp(1)*mf
750 <                      f_Row(2,atom1) = f_Row(2,atom1) + swderiv*d_grp(2)*mf
751 <                      f_Row(3,atom1) = f_Row(3,atom1) + swderiv*d_grp(3)*mf
752 <                   enddo
753 <                  
754 <                   do jb=groupStart(j), groupStart(j+1)-1
755 <                      atom2=groupList(jb)
756 <                      mf = mfact(atom2)
757 <                      f_Col(1,atom2) = f_Col(1,atom2) - swderiv*d_grp(1)*mf
758 <                      f_Col(2,atom2) = f_Col(2,atom2) - swderiv*d_grp(2)*mf
759 <                      f_Col(3,atom2) = f_Col(3,atom2) - swderiv*d_grp(3)*mf
760 <                   enddo                        
561 >                if (loop .eq. PAIR_LOOP) then
562 >                   vij = 0.0d0
563 >                   fij(1:3) = 0.0d0
564                  endif
762
763             end if
764          enddo
765       enddo
766
767       point(nrow_group + 1) = nlist + 1          
768      
769    else  !! (of update_check)
770      
771       ! use the list to find the neighbors
772       do i = 1, nrow_group
773
774          n_in_i = groupStart(i+1) - groupStart(i)
775          
776          JBEG = POINT(i)
777          JEND = POINT(i+1) - 1
778          ! check that group i has neighbors
779          if (jbeg .le. jend) then
780            
781             do jnab = jbeg, jend
782                j = list(jnab)
783                              
784                call get_interatomic_vector(q_group_Row(:,i), &
785                     q_group_Col(:,j), d_grp, rgrpsq)
565                  
787                vij = 0.0d0
566                  call get_switch(rgrpsq, sw, dswdr, rgrp, group_switch, &
567                       in_switching_region)
568                  
569 <                n_in_j = groupStart(j+1) - groupStart(j)
569 >                n_in_j = groupStartCol(j+1) - groupStartCol(j)
570                  
571 <                do ia = groupStart(i), groupStart(i+1)-1
794 <                   atom1 = groupList(ia)
571 >                do ia = groupStartRow(i), groupStartRow(i+1)-1
572                    
573 <                   inner2: do jb = groupStart(j), groupStart(j+1)-1
574 <                      atom2 = groupList(jb)                        
573 >                   atom1 = groupListRow(ia)
574 >                  
575 >                   inner: do jb = groupStartCol(j), groupStartCol(j+1)-1
576                        
577 <                      if (skipThisPair(atom1, atom2)) cycle inner2
578 <
577 >                      atom2 = groupListCol(jb)
578 >                      
579 >                      if (skipThisPair(atom1, atom2)) cycle inner
580 >                      
581                        if ((n_in_i .eq. 1).and.(n_in_j .eq. 1)) then
582                           d_atm(1:3) = d_grp(1:3)
583                           ratmsq = rgrpsq
584                        else
585 + #ifdef IS_MPI
586                           call get_interatomic_vector(q_Row(:,atom1), &
587                                q_Col(:,atom2), d_atm, ratmsq)
807                      endif
808                                            
809                      call do_pair(atom1, atom2, ratmsq, d_atm, sw, &
810                           do_pot, do_stress, &
811                           u_l, A, f, t, pot_local, vpair)
812                      
813                      vij = vij + vpair
814                                            
815                   enddo inner2
816                enddo
817                
818                if (in_switching_region) then
819                   swderiv = vij*dswdr/rgrp
820  
821                   do ia=groupStart(i), groupStart(i+1)-1
822                      atom1=groupList(ia)
823                      mf = mfact(atom1)                  
824                      f_Row(1,atom1) = f_Row(1,atom1) + swderiv*d_grp(1)*mf
825                      f_Row(2,atom1) = f_Row(2,atom1) + swderiv*d_grp(2)*mf
826                      f_Row(3,atom1) = f_Row(3,atom1) + swderiv*d_grp(3)*mf
827                   enddo
828                  
829                   do jb=groupStart(j), groupStart(j+1)-1
830                      atom2=groupList(jb)
831                      mf = mfact(atom2)
832                      f_Col(1,atom2) = f_Col(1,atom2) - swderiv*d_grp(1)*mf
833                      f_Col(2,atom2) = f_Col(2,atom2) - swderiv*d_grp(2)*mf
834                      f_Col(3,atom2) = f_Col(3,atom2) - swderiv*d_grp(3)*mf
835                   enddo
836                endif
837
838             enddo
839          endif
840       enddo
841    endif
842    
588   #else
844
845    if (update_nlist) then
846      
847       !! save current configuration, construct neighbor list,
848       !! and calculate forces
849      
850       call saveNeighborList(nGroup, q_group)
851      
852       neighborListSize = size(list)
853       nlist = 0      
854      
855       do i = 1, nGroup-1
856
857          point(i) = nlist + 1
858          n_in_i = groupStart(i+1) - groupStart(i)
859          
860          do j = i+1, nGroup
861            
862             call get_interatomic_vector(q_group(:,i), &
863                  q_group(:,j), d_grp, rgrpsq)
864            
865             if (rgrpsq < rlistsq) then
866                nlist = nlist + 1
867                
868                if (nlist > neighborListSize) then
869                   call expandNeighborList(nGroup, listerror)
870                   if (listerror /= 0) then
871                      error = -1
872                      write(DEFAULT_ERROR,*) "ERROR: nlist > list size and max allocations exceeded."
873                      return
874                   end if
875                   neighborListSize = size(list)
876                endif
877                
878                list(nlist) = j
879
880                vij = 0.0d0
881
882                call get_switch(rgrpsq, sw, dswdr, rgrp, group_switch, &
883                     in_switching_region)
884                
885                n_in_j = groupStart(j+1) - groupStart(j)
886
887                do ia = groupStart(i), groupStart(i+1)-1
888                   atom1 = groupList(ia)
889                  
890                   inner1: do jb = groupStart(j), groupStart(j+1)-1
891                      atom2 = groupList(jb)
892                      
893                      if (skipThisPair(atom1, atom2)) cycle inner1
894                      
895                      if ((n_in_i .eq. 1).and.(n_in_j .eq. 1)) then
896                         d_atm(1:3) = d_grp(1:3)
897                         ratmsq = rgrpsq
898                      else
589                           call get_interatomic_vector(q(:,atom1), &
590                                q(:,atom2), d_atm, ratmsq)
591 + #endif
592                        endif
593 <                        
594 <                      call do_pair(atom1, atom2, ratmsq, d_atm, sw, &
595 <                           do_pot, do_stress, &
596 <                           u_l, A, f, t, pot, vpair)
593 >                      if (loop .eq. PREPAIR_LOOP) then
594 > #ifdef IS_MPI                      
595 >                         call do_prepair(atom1, atom2, ratmsq, d_atm, sw, &
596 >                              rgrpsq, d_grp, do_pot, do_stress, &
597 >                              u_l, A, f, t, pot_local)
598 > #else
599 >                         call do_prepair(atom1, atom2, ratmsq, d_atm, sw, &
600 >                              rgrpsq, d_grp, do_pot, do_stress, &
601 >                              u_l, A, f, t, pot)
602 > #endif                                              
603 >                      else
604 > #ifdef IS_MPI                      
605 >                         call do_pair(atom1, atom2, ratmsq, d_atm, sw, &
606 >                              do_pot, &
607 >                              u_l, A, f, t, pot_local, vpair, fpair)
608 > #else
609 >                         call do_pair(atom1, atom2, ratmsq, d_atm, sw, &
610 >                              do_pot,  &
611 >                              u_l, A, f, t, pot, vpair, fpair)
612 > #endif
613 >                         vij = vij + vpair
614 >                         fij(1:3) = fij(1:3) + fpair(1:3)
615 >                      endif
616 >                   enddo inner
617 >                enddo
618 >                
619 >                if (loop .eq. PAIR_LOOP) then
620 >                   if (in_switching_region) then
621 >                      swderiv = vij*dswdr/rgrp
622 >                      fij(1) = fij(1) + swderiv*d_grp(1)
623 >                      fij(2) = fij(2) + swderiv*d_grp(2)
624 >                      fij(3) = fij(3) + swderiv*d_grp(3)
625                        
626 <                      vij = vij + vpair
626 >                      do ia=groupStartRow(i), groupStartRow(i+1)-1
627 >                         atom1=groupListRow(ia)
628 >                         mf = mfactRow(atom1)
629 > #ifdef IS_MPI
630 >                         f_Row(1,atom1) = f_Row(1,atom1) + swderiv*d_grp(1)*mf
631 >                         f_Row(2,atom1) = f_Row(2,atom1) + swderiv*d_grp(2)*mf
632 >                         f_Row(3,atom1) = f_Row(3,atom1) + swderiv*d_grp(3)*mf
633 > #else
634 >                         f(1,atom1) = f(1,atom1) + swderiv*d_grp(1)*mf
635 >                         f(2,atom1) = f(2,atom1) + swderiv*d_grp(2)*mf
636 >                         f(3,atom1) = f(3,atom1) + swderiv*d_grp(3)*mf
637 > #endif
638 >                      enddo
639                        
640 <                   enddo inner1
641 <                enddo
642 <
643 <                if (in_switching_region) then
644 <                   swderiv = vij*dswdr/rgrp
645 <                   do ia=groupStart(i), groupStart(i+1)-1
646 <                      atom1=groupList(ia)
647 <                      mf = mfact(atom1)                  
648 <                      f(1,atom1) = f(1,atom1) + swderiv*d_grp(1)*mf
649 <                      f(2,atom1) = f(2,atom1) + swderiv*d_grp(2)*mf
650 <                      f(3,atom1) = f(3,atom1) + swderiv*d_grp(3)*mf
651 <                   enddo
640 >                      do jb=groupStartCol(j), groupStartCol(j+1)-1
641 >                         atom2=groupListCol(jb)
642 >                         mf = mfactCol(atom2)
643 > #ifdef IS_MPI
644 >                         f_Col(1,atom2) = f_Col(1,atom2) - swderiv*d_grp(1)*mf
645 >                         f_Col(2,atom2) = f_Col(2,atom2) - swderiv*d_grp(2)*mf
646 >                         f_Col(3,atom2) = f_Col(3,atom2) - swderiv*d_grp(3)*mf
647 > #else
648 >                         f(1,atom2) = f(1,atom2) - swderiv*d_grp(1)*mf
649 >                         f(2,atom2) = f(2,atom2) - swderiv*d_grp(2)*mf
650 >                         f(3,atom2) = f(3,atom2) - swderiv*d_grp(3)*mf
651 > #endif
652 >                      enddo
653 >                   endif
654                    
655 <                   do jb=groupStart(j), groupStart(j+1)-1
923 <                      atom2=groupList(jb)
924 <                      mf = mfact(atom2)
925 <                      f(1,atom2) = f(1,atom2) - swderiv*d_grp(1)*mf
926 <                      f(2,atom2) = f(2,atom2) - swderiv*d_grp(2)*mf
927 <                      f(3,atom2) = f(3,atom2) - swderiv*d_grp(3)*mf
928 <                   enddo
655 >                   if (do_stress) call add_stress_tensor(d_grp, fij)
656                  endif
930
657               end if
658            enddo
659 <       enddo
934 <       point(nGroup) = nlist + 1          
659 >       enddo outer
660        
661 <    else  !! (of update_check)
662 <      
663 <       ! use the list to find the neighbors
664 <       do i = 1, nGroup-1
665 <
666 <          n_in_i = groupStart(i+1) - groupStart(i)
667 <          
668 <          JBEG = POINT(i)
669 <          JEND = POINT(i+1) - 1
670 <          ! check that group i has neighbors
671 <          if (jbeg .le. jend) then
947 <            
948 <             do jnab = jbeg, jend
949 <                j = list(jnab)
950 <                
951 <                call get_interatomic_vector(q_group(:,i), &
952 <                     q_group(:,j), d_grp, rgrpsq)
953 <
954 <                vij = 0.0d0    
955 <                
956 <                call get_switch(rgrpsq, sw, dswdr, rgrp, group_switch, &
957 <                     in_switching_region)
958 <                
959 <                n_in_j = groupStart(j+1) - groupStart(j)
960 <                
961 <                do ia = groupStart(i), groupStart(i+1)-1
962 <                   atom1 = groupList(ia)
963 <                  
964 <                   inner2: do jb = groupStart(j), groupStart(j+1)-1
965 <                      atom2 = groupList(jb)                      
966 <
967 <                      if (skipThisPair(atom1, atom2)) cycle inner2
968 <                      
969 <                      if ((n_in_i .eq. 1).and.(n_in_j .eq. 1)) then
970 <                         d_atm(1:3) = d_grp(1:3)
971 <                         ratmsq = rgrpsq
972 <                      else
973 <                         call get_interatomic_vector(q(:,atom1), &
974 <                              q(:,atom2), d_atm, ratmsq)
975 <                      endif
976 <                      
977 <                      call do_pair(atom1, atom2, ratmsq, d_atm, sw, &
978 <                           do_pot, do_stress, &
979 <                           u_l, A, f, t, pot, vpair)
980 <                      
981 <                      vij = vij + vpair
982 <                      
983 <                   enddo inner2
984 <                enddo
985 <                
986 <                if (in_switching_region) then
987 <                   swderiv = vij*dswdr/rgrp
988 <                  
989 <                   do ia=groupStart(i), groupStart(i+1)-1
990 <                      atom1=groupList(ia)
991 <                      mf = mfact(atom1)                  
992 <                      f(1,atom1) = f(1,atom1) + swderiv*d_grp(1)*mf
993 <                      f(2,atom1) = f(2,atom1) + swderiv*d_grp(2)*mf
994 <                      f(3,atom1) = f(3,atom1) + swderiv*d_grp(3)*mf
995 <                   enddo
996 <                  
997 <                   do jb=groupStart(j), groupStart(j+1)-1
998 <                      atom2=groupList(jb)
999 <                      mf = mfact(atom2)
1000 <                      f(1,atom2) = f(1,atom2) - swderiv*d_grp(1)*mf
1001 <                      f(2,atom2) = f(2,atom2) - swderiv*d_grp(2)*mf
1002 <                      f(3,atom2) = f(3,atom2) - swderiv*d_grp(3)*mf
1003 <                   enddo
1004 <                endif
1005 <             enddo
661 >       if (update_nlist) then
662 > #ifdef IS_MPI
663 >          point(nGroupsInRow + 1) = nlist + 1
664 > #else
665 >          point(nGroups) = nlist + 1
666 > #endif
667 >          if (loop .eq. PREPAIR_LOOP) then
668 >             ! we just did the neighbor list update on the first
669 >             ! pass, so we don't need to do it
670 >             ! again on the second pass
671 >             update_nlist = .false.                              
672            endif
673 <       enddo
674 <    endif
673 >       endif
674 >            
675 >       if (loop .eq. PREPAIR_LOOP) then
676 >          call do_preforce(nlocal, pot)
677 >       endif
678 >      
679 >    enddo
680      
1010 #endif
1011    
1012    ! phew, done with main loop.
1013    
681      !! Do timing
682   #ifdef PROFILE
683      call cpu_time(forceTimeFinal)
# Line 1021 | Line 688 | contains
688      !!distribute forces
689      
690      f_temp = 0.0_dp
691 <    call scatter(f_Row,f_temp,plan_row3d)
691 >    call scatter(f_Row,f_temp,plan_atom_row_3d)
692      do i = 1,nlocal
693         f(1:3,i) = f(1:3,i) + f_temp(1:3,i)
694      end do
695      
696      f_temp = 0.0_dp
697 <    call scatter(f_Col,f_temp,plan_col3d)
697 >    call scatter(f_Col,f_temp,plan_atom_col_3d)
698      do i = 1,nlocal
699         f(1:3,i) = f(1:3,i) + f_temp(1:3,i)
700      end do
701      
702      if (FF_UsesDirectionalAtoms() .and. SIM_uses_directional_atoms) then
703         t_temp = 0.0_dp
704 <       call scatter(t_Row,t_temp,plan_row3d)
704 >       call scatter(t_Row,t_temp,plan_atom_row_3d)
705         do i = 1,nlocal
706            t(1:3,i) = t(1:3,i) + t_temp(1:3,i)
707         end do
708         t_temp = 0.0_dp
709 <       call scatter(t_Col,t_temp,plan_col3d)
709 >       call scatter(t_Col,t_temp,plan_atom_col_3d)
710        
711         do i = 1,nlocal
712            t(1:3,i) = t(1:3,i) + t_temp(1:3,i)
# Line 1048 | Line 715 | contains
715      
716      if (do_pot) then
717         ! scatter/gather pot_row into the members of my column
718 <       call scatter(pot_Row, pot_Temp, plan_row)
718 >       call scatter(pot_Row, pot_Temp, plan_atom_row)
719        
720         ! scatter/gather pot_local into all other procs
721         ! add resultant to get total pot
# Line 1058 | Line 725 | contains
725        
726         pot_Temp = 0.0_DP
727        
728 <       call scatter(pot_Col, pot_Temp, plan_col)
728 >       call scatter(pot_Col, pot_Temp, plan_atom_col)
729         do i = 1, nlocal
730            pot_local = pot_local + pot_Temp(i)
731         enddo
# Line 1071 | Line 738 | contains
738         if (FF_uses_RF .and. SIM_uses_RF) then
739            
740   #ifdef IS_MPI
741 <          call scatter(rf_Row,rf,plan_row3d)
742 <          call scatter(rf_Col,rf_Temp,plan_col3d)
741 >          call scatter(rf_Row,rf,plan_atom_row_3d)
742 >          call scatter(rf_Col,rf_Temp,plan_atom_col_3d)
743            do i = 1,nlocal
744               rf(1:3,i) = rf(1:3,i) + rf_Temp(1:3,i)
745            end do
# Line 1132 | Line 799 | contains
799      endif
800      
801   #endif
802 <    
1136 <    
802 >      
803    end subroutine do_force_loop
1138
804    
805 <  subroutine do_pair(i, j, rijsq, d, sw, do_pot, do_stress, &
806 <       u_l, A, f, t, pot, vpair)
805 >  subroutine do_pair(i, j, rijsq, d, sw, do_pot, &
806 >       u_l, A, f, t, pot, vpair, fpair)
807  
808      real( kind = dp ) :: pot, vpair, sw
809 +    real( kind = dp ), dimension(3) :: fpair
810      real( kind = dp ), dimension(nLocal)   :: mfact
811      real( kind = dp ), dimension(3,nLocal) :: u_l
812      real( kind = dp ), dimension(9,nLocal) :: A
813      real( kind = dp ), dimension(3,nLocal) :: f
814      real( kind = dp ), dimension(3,nLocal) :: t
815  
816 <    logical, intent(inout) :: do_pot, do_stress
816 >    logical, intent(inout) :: do_pot
817      integer, intent(in) :: i, j
818      real ( kind = dp ), intent(inout) :: rijsq
819      real ( kind = dp )                :: r
# Line 1156 | Line 822 | contains
822  
823      r = sqrt(rijsq)
824      vpair = 0.0d0
825 +    fpair(1:3) = 0.0d0
826  
827   #ifdef IS_MPI
828 <    if (tagRow(i) .eq. tagColumn(j)) then
829 <       write(0,*) 'do_pair is doing', i , j, tagRow(i), tagColumn(j)
828 >    if (AtomRowToGlobal(i) .eq. AtomColToGlobal(j)) then
829 >       write(0,*) 'do_pair is doing', i , j, AtomRowToGlobal(i), AtomColToGlobal(j)
830      endif
831      me_i = atid_row(i)
832      me_j = atid_col(j)
# Line 1177 | Line 844 | contains
844            !write(*,'(3es12.3)') sw, vpair, pot
845            !write(*,*)
846  
847 <          call do_lj_pair(i, j, d, r, rijsq, sw, vpair, pot, f, do_pot, &
1181 <               do_stress)
847 >          call do_lj_pair(i, j, d, r, rijsq, sw, vpair, fpair, pot, f, do_pot)
848         endif
849        
850      endif
# Line 1186 | Line 852 | contains
852      if (FF_uses_charges .and. SIM_uses_charges) then
853        
854         if (PropertyMap(me_i)%is_Charge .and. PropertyMap(me_j)%is_Charge) then
855 <          call do_charge_pair(i, j, d, r, rijsq, sw, vpair, pot, f, do_pot, &
1190 <               do_stress)
855 >          call do_charge_pair(i, j, d, r, rijsq, sw, vpair, fpair, pot, f, do_pot)
856         endif
857        
858      endif
# Line 1195 | Line 860 | contains
860      if (FF_uses_dipoles .and. SIM_uses_dipoles) then
861        
862         if ( PropertyMap(me_i)%is_DP .and. PropertyMap(me_j)%is_DP) then
863 <          call do_dipole_pair(i, j, d, r, rijsq, sw, vpair, pot, u_l, f, t, &
864 <               do_pot, do_stress)
863 >          call do_dipole_pair(i, j, d, r, rijsq, sw, vpair, fpair, pot, u_l, f, t, &
864 >               do_pot)
865            if (FF_uses_RF .and. SIM_uses_RF) then
866               call accumulate_rf(i, j, r, u_l, sw)
867 <             call rf_correct_forces(i, j, d, r, u_l, sw, f, do_stress)
867 >             call rf_correct_forces(i, j, d, r, u_l, sw, f, fpair)
868            endif          
869         endif
870  
# Line 1208 | Line 873 | contains
873      if (FF_uses_Sticky .and. SIM_uses_sticky) then
874  
875         if ( PropertyMap(me_i)%is_Sticky .and. PropertyMap(me_j)%is_Sticky) then
876 <          call do_sticky_pair(i, j, d, r, rijsq, sw, vpair, pot, A, f, t, &
877 <               do_pot, do_stress)
876 >          call do_sticky_pair(i, j, d, r, rijsq, sw, vpair, fpair, pot, A, f, t, &
877 >               do_pot)
878         endif
879  
880      endif
# Line 1218 | Line 883 | contains
883      if (FF_uses_GB .and. SIM_uses_GB) then
884        
885         if ( PropertyMap(me_i)%is_GB .and. PropertyMap(me_j)%is_GB) then
886 <          call do_gb_pair(i, j, d, r, rijsq, sw, vpair, pot, u_l, f, t, &
887 <               do_pot, do_stress)          
886 >          call do_gb_pair(i, j, d, r, rijsq, sw, vpair, fpair, pot, u_l, f, t, &
887 >               do_pot)
888         endif
889  
890      endif
# Line 1227 | Line 892 | contains
892      if (FF_uses_EAM .and. SIM_uses_EAM) then
893        
894         if ( PropertyMap(me_i)%is_EAM .and. PropertyMap(me_j)%is_EAM) then
895 <          call do_eam_pair(i, j, d, r, rijsq, sw, vpair, pot, f, &
896 <               do_pot, do_stress)
895 >          call do_eam_pair(i, j, d, r, rijsq, sw, vpair, fpair, pot, f, &
896 >               do_pot)
897         endif
898        
899      endif
900      
901    end subroutine do_pair
902  
903 <  subroutine do_prepair(i, j, rijsq, d, rcijsq, dc, &
903 >  subroutine do_prepair(i, j, rijsq, d, sw, rcijsq, dc, &
904         do_pot, do_stress, u_l, A, f, t, pot)
905 <   real( kind = dp ) :: pot
905 >
906 >   real( kind = dp ) :: pot, sw
907     real( kind = dp ), dimension(3,nLocal) :: u_l
908     real (kind=dp), dimension(9,nLocal) :: A
909     real (kind=dp), dimension(3,nLocal) :: f
# Line 1263 | Line 929 | contains
929    
930  
931   #ifdef IS_MPI
932 <   if (tagRow(i) .eq. tagColumn(j)) then
933 <      write(0,*) 'do_pair is doing', i , j, tagRow(i), tagColumn(j)
932 >   if (AtomRowToGlobal(i) .eq. AtomColToGlobal(j)) then
933 >      write(0,*) 'do_prepair is doing', i , j, AtomRowToGlobal(i), AtomColToGlobal(j)
934     endif
935    
936     me_i = atid_row(i)
# Line 1276 | Line 942 | contains
942     me_j = atid(j)
943    
944   #endif
945 <    
945 >  
946     if (FF_uses_EAM .and. SIM_uses_EAM) then
947 <
947 >      
948        if (PropertyMap(me_i)%is_EAM .and. PropertyMap(me_j)%is_EAM) &
949             call calc_EAM_prepair_rho(i, j, d, r, rijsq )
950 <
950 >      
951     endif
952    
953   end subroutine do_prepair
954 <
955 <
1290 <
1291 <
954 >
955 >
956   subroutine do_preforce(nlocal,pot)
957     integer :: nlocal
958     real( kind = dp ) :: pot
# Line 1413 | Line 1077 | contains
1077    
1078   #ifdef IS_MPI
1079     !! in MPI, we have to look up the unique IDs for each atom
1080 <   unique_id_1 = tagRow(atom1)
1080 >   unique_id_1 = AtomRowToGlobal(atom1)
1081   #else
1082     !! in the normal loop, the atom numbers are unique
1083     unique_id_1 = atom1
# Line 1432 | Line 1096 | contains
1096     end if
1097    
1098   #ifdef IS_MPI
1099 <   unique_id_2 = tagColumn(atom2)
1099 >   unique_id_2 = AtomColToGlobal(atom2)
1100   #else
1101     unique_id_2 = atom2
1102   #endif
# Line 1501 | Line 1165 | contains
1165   #endif
1166  
1167   !! This cleans componets of force arrays belonging only to fortran
1168 +
1169 + subroutine add_stress_tensor(dpair, fpair)
1170 +  
1171 +   real( kind = dp ), dimension(3), intent(in) :: dpair, fpair
1172 +  
1173 +   ! because the d vector is the rj - ri vector, and
1174 +   ! because fx, fy, fz are the force on atom i, we need a
1175 +   ! negative sign here:  
1176 +  
1177 +   tau_Temp(1) = tau_Temp(1) - dpair(1) * fpair(1)
1178 +   tau_Temp(2) = tau_Temp(2) - dpair(1) * fpair(2)
1179 +   tau_Temp(3) = tau_Temp(3) - dpair(1) * fpair(3)
1180 +   tau_Temp(4) = tau_Temp(4) - dpair(2) * fpair(1)
1181 +   tau_Temp(5) = tau_Temp(5) - dpair(2) * fpair(2)
1182 +   tau_Temp(6) = tau_Temp(6) - dpair(2) * fpair(3)
1183 +   tau_Temp(7) = tau_Temp(7) - dpair(3) * fpair(1)
1184 +   tau_Temp(8) = tau_Temp(8) - dpair(3) * fpair(2)
1185 +   tau_Temp(9) = tau_Temp(9) - dpair(3) * fpair(3)
1186 +  
1187 +   !write(*,'(6es12.3)')  fpair(1:3), tau_Temp(1), tau_Temp(5), tau_temp(9)
1188 +   virial_Temp = virial_Temp + &
1189 +        (tau_Temp(1) + tau_Temp(5) + tau_Temp(9))
1190 +  
1191 + end subroutine add_stress_tensor
1192  
1193   end module do_Forces
1194 +

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines