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 1138 by gezelter, Wed Apr 28 21:39:22 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.52 2004-04-28 21:39:22 gezelter Exp $, $Date: 2004-04-28 21:39:22 $, $Name: not supported by cvs2svn $, $Revision: 1.52 $
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
11    use simulation
12    use definitions
13    use atype_module
14 +  use switcheroo
15    use neighborLists  
16    use lj
17    use sticky_pair
# Line 30 | Line 31 | module do_Forces
31  
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.
41    logical, save :: havePolicies = .false.
# Line 63 | Line 68 | module do_Forces
68    public :: do_force_loop
69    public :: setRlistDF
70  
66
71   #ifdef PROFILE
72    public :: getforcetime
73    real, save :: forceTime = 0
# Line 161 | Line 165 | contains
165      SIM_requires_prepair_calc = SimRequiresPrepairCalc()
166      SIM_uses_directional_atoms = SimUsesDirectionalAtoms()
167      SIM_uses_PBC = SimUsesPBC()
168 <    SIM_uses_molecular_cutoffs = SimUsesMolecularCutoffs()
168 >    !SIM_uses_molecular_cutoffs = SimUsesMolecularCutoffs()
169  
170      haveSIMvariables = .true.
171  
# Line 279 | Line 283 | contains
283      
284      !! Assume sanity (for the sake of argument)
285      haveSaneForceField = .true.
282    !!
283    if (FF_uses_charges) then
284      dielect = getDielect()
285      call initialize_charge(dielect)
286    endif
286  
288
287      !! check to make sure the FF_uses_RF setting makes sense
288      
289      if (FF_uses_dipoles) then
# Line 364 | Line 362 | contains
362         endif
363         haveNeighborList = .true.
364      endif
365 +
366      
367 +    
368    end subroutine init_FF
369    
370  
371    !! Does force loop over i,j pairs. Calls do_pair to calculates forces.
372    !------------------------------------------------------------->
373 <  subroutine do_force_loop(q, qcom, mfact, A, u_l, f, t, tau, pot, &
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,nLocal) :: qcom
379 <    !! mass factors used for molecular cutoffs
380 <    real ( kind = dp ), dimension(3,nLocal) :: mfact
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 393 | Line 391 | contains
391      logical ( kind = 2) :: do_pot_c, do_stress_c
392      logical :: do_pot
393      logical :: do_stress
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 :: 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 ) ::  rijsq, rcijsq
410 <    real(kind=dp),dimension(3) :: d, dc
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, 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)
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 440 | 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)
452 <    
453 <    if (SIM_uses_molecular_cutoffs) then
454 <       call gather(qcom,qcom_Row,plan_row3d)
455 <       call gather(qcom,qcom_Col,plan_col3d)
449 <    endif
450 <    
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_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 <       if (SIM_uses_molecular_cutoffs) then
476 <          call checkNeighborList(nlocal, qcom, listSkin, update_nlist)
477 <       else
478 <          call checkNeighborList(nlocal, q, listSkin, update_nlist)  
474 >       loopStart = PREPAIR_LOOP
475 >    else
476 >       loopStart = PAIR_LOOP
477 >    endif
478 >
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 >          call checkNeighborList(nGroups, q_group, listSkin, update_nlist)
485         endif
474       !! if_mpi_gather_stuff_for_prepair
475       !! do_prepair_loop_if_needed
476       !! if_mpi_scatter_stuff_from_prepair
477       !! if_mpi_gather_stuff_from_prepair_to_main_loop
486        
479       !--------------------PREFORCE LOOP----------->>>>>>>>>>>>>>>>>>>>>>>>>>>
480 #ifdef IS_MPI
481      
487         if (update_nlist) then
488 <          
489 <          !! save current configuration, construct neighbor list,
490 <          !! and calculate forces
491 <          if (SIM_uses_molecular_cutoffs) then
492 <             call saveNeighborList(nlocal, qcom)
493 <          else
489 <             call saveNeighborList(nlocal, q)
490 <          endif
491 <          
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      
494 <          
495 <          do i = 1, nrow
496 <             point(i) = nlist + 1
497 <            
498 <             prepair_inner: do j = 1, ncol
499 <                
500 <                if (skipThisPair(i,j)) cycle prepair_inner
501 <                
502 <                if (SIM_uses_molecular_cutoffs) then
503 <                   call get_interatomic_vector(qcom_Row(:,i), qcom_Col(:,j), &
504 <                        dc, rcijsq)
505 <                else
506 <                   call get_interatomic_vector(q_Row(:,i), q_Col(:,j), &
507 <                        dc, rcijsq)
508 <                endif
509 <                
510 <                if (rcijsq < rlistsq) then            
511 <                  
512 <                   nlist = nlist + 1
513 <                  
514 <                   if (nlist > neighborListSize) then
515 <                      call expandNeighborList(nlocal, listerror)
516 <                      if (listerror /= 0) then
517 <                         error = -1
518 <                         write(DEFAULT_ERROR,*) "ERROR: nlist > list size and max allocations exceeded."
519 <                         return
520 <                      end if
521 <                      neighborListSize = size(list)
522 <                   endif
523 <                  
524 <                   list(nlist) = j
525 <                  
526 <                   if (SIM_uses_molecular_cutoffs) then
527 <                      ! since the simulation distances were in molecular COMs:
528 <                      call get_interatomic_vector(q_Row(:,i), q_Col(:,j), &
529 <                           d, rijsq)
530 <                   else
531 <                      d(1:3) = dc(1:3)
532 <                      rijsq = rcijsq
533 <                   endif
534 <                  
535 <                   call do_prepair(i, j, rijsq, d, rcijsq, dc, &
536 <                        do_pot, do_stress, u_l, A, f, t, pot_local)
537 <                endif
538 <             enddo prepair_inner
539 <          enddo
540 <          
541 <          point(nrow + 1) = nlist + 1
542 <          
543 <       else  !! (of update_check)
544 <          
545 <          ! use the list to find the neighbors
546 <          do i = 1, nrow
547 <             JBEG = POINT(i)
548 <             JEND = POINT(i+1) - 1
549 <             ! check thiat molecule i has neighbors
550 <             if (jbeg .le. jend) then
551 <                
552 <                do jnab = jbeg, jend
553 <                   j = list(jnab)
554 <                                      
555 <                   call get_interatomic_vector(q_Row(:,i), q_Col(:,j), &
556 <                        d, rijsq)
557 <                   if (SIM_uses_molecular_cutoffs) then
558 <                      call get_interatomic_vector(qcom_Row(:,i),qcom_Col(:,j),&
559 <                           dc, rcijsq)
560 <                   else
561 <                      dc(1:3) = d(1:3)
562 <                      rcijsq = rijsq
563 <                   endif
564 <                  
565 <                   call do_prepair(i, j, rijsq, d, rcijsq, dc, &
566 <                        do_pot, do_stress, u_l, A, f, t, pot_local)
567 <                  
568 <                enddo
569 <             endif
570 <          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, contruct neighbor list,
578 <          ! and calculate forces
579 <          call saveNeighborList(natoms, q)
506 >          if (update_nlist) point(i) = nlist + 1
507            
508 <          neighborListSize = size(list)
508 >          n_in_i = groupStartRow(i+1) - groupStartRow(i)
509            
510 <          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, natoms-1
526 <             point(i) = nlist + 1
527 <            
528 <             prepair_inner: do j = i+1, natoms
529 <                
530 <                if (skipThisPair(i,j))  cycle prepair_inner
531 <                
532 <                if (SIM_uses_molecular_cutoffs) then
533 <                   call get_interatomic_vector(qcom(:,i), qcom(:,j), &
534 <                        dc, rcijsq)
535 <                else
536 <                   call get_interatomic_vector(q(:,i), q(:,j), dc, rcijsq)
537 <                endif
538 <                
539 <                if (rcijsq < rlistsq) then
540 <                  
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(natoms, 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 611 | Line 556 | contains
556                     endif
557                    
558                     list(nlist) = j
614                  
615                  
616                   if (SIM_uses_molecular_cutoffs) then
617                      ! since the simulation distances were in molecular COMs:
618                      call get_interatomic_vector(q(:,i), q(:,j), &
619                           d, rijsq)
620                   else
621                      dc(1:3) = d(1:3)
622                      rcijsq = rijsq
623                   endif
624                  
625                   call do_prepair(i, j, rijsq, d, rcijsq, dc, &
626                        do_pot, do_stress, u_l, A, f, t, pot)
627                  
559                  endif
629             enddo prepair_inner
630          enddo
631          
632          point(natoms) = nlist + 1
633          
634       else !! (update)
635          
636          ! use the list to find the neighbors
637          do i = 1, natoms-1
638             JBEG = POINT(i)
639             JEND = POINT(i+1) - 1
640             ! check thiat molecule i has neighbors
641             if (jbeg .le. jend) then
560                  
561 <                do jnab = jbeg, jend
562 <                   j = list(jnab)
561 >                if (loop .eq. PAIR_LOOP) then
562 >                   vij = 0.0d0
563 >                   fij(1:3) = 0.0d0
564 >                endif
565 >                
566 >                call get_switch(rgrpsq, sw, dswdr, rgrp, group_switch, &
567 >                     in_switching_region)
568 >                
569 >                n_in_j = groupStartCol(j+1) - groupStartCol(j)
570 >                
571 >                do ia = groupStartRow(i), groupStartRow(i+1)-1
572                    
573 <                   call get_interatomic_vector(q(:,i), q(:,j), d, rijsq)
574 <                   if (SIM_uses_molecular_cutoffs) then
575 <                      call get_interatomic_vector(qcom(:,i), qcom(:,j), &
576 <                           dc, rcijsq)
577 <                   else
578 <                      dc(1:3) = d(1:3)
579 <                      rcijsq = rijsq
573 >                   atom1 = groupListRow(ia)
574 >                  
575 >                   inner: do jb = groupStartCol(j), groupStartCol(j+1)-1
576 >                      
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)
588 > #else
589 >                         call get_interatomic_vector(q(:,atom1), &
590 >                              q(:,atom2), d_atm, ratmsq)
591 > #endif
592 >                      endif
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 >                      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 >                      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 <                   call do_prepair(i, j, rijsq, d, rcijsq, dc, &
656 <                        do_pot, do_stress, u_l, A, f, t, pot)
657 <                  
658 <                enddo
659 <             endif
655 >                   if (do_stress) call add_stress_tensor(d_grp, fij)
656 >                endif
657 >             end if
658            enddo
659 <       endif
662 < #endif
663 <       !! Do rest of preforce calculations
664 <       !! do necessary preforce calculations  
665 <       call do_preforce(nlocal,pot)
666 <       ! we have already updated the neighbor list set it to false...
667 <       update_nlist = .false.
668 <    else
669 <       !! See if we need to update neighbor lists for non pre-pair
670 <       call checkNeighborList(nlocal, q, listSkin, update_nlist)  
671 <    endif
672 <    
673 <    !---------------------------------MAIN Pair LOOP->>>>>>>>>>>>>
674 <    
675 < #ifdef IS_MPI
676 <    
677 <    if (update_nlist) then
678 <       !! save current configuration, construct neighbor list,
679 <       !! and calculate forces
680 <       call saveNeighborList(nlocal, q)
659 >       enddo outer
660        
661 <       neighborListSize = size(list)
662 <       nlist = 0      
663 <      
664 <       do i = 1, nrow
665 <          
666 <          point(i) = nlist + 1
667 <          
668 <          inner: do j = 1, ncol
669 <            
670 <             if (skipThisPair(i,j)) cycle inner
671 <            
693 <             if (SIM_uses_molecular_cutoffs) then
694 <                call get_interatomic_vector(qcom_Row(:,i), qcom_Col(:,j), &
695 <                     dc, rcijsq)
696 <             else
697 <                call get_interatomic_vector(q_Row(:,i), q_Col(:,j), &
698 <                     dc, rcijsq)
699 <             endif
700 <            
701 <             if (rcijsq < rlistsq) then            
702 <                
703 <                nlist = nlist + 1
704 <                
705 <                if (nlist > neighborListSize) then
706 <                   call expandNeighborList(nlocal, listerror)
707 <                   if (listerror /= 0) then
708 <                      error = -1
709 <                      write(DEFAULT_ERROR,*) "ERROR: nlist > list size and max allocations exceeded."
710 <                      return
711 <                   end if
712 <                   neighborListSize = size(list)
713 <                endif
714 <                
715 <                list(nlist) = j
716 <                
717 <                if (SIM_uses_molecular_cutoffs) then
718 <                   call get_interatomic_vector(q_Row(:,i), q_Col(:,j), &
719 <                        d, rijsq)
720 <                else
721 <                   d(1:3) = dc(1:3)
722 <                   rijsq = rcijsq
723 <                endif
724 <                
725 <                call do_pair(i, j, rijsq, d, rcijsq, dc, mfact, &
726 <                     do_pot, do_stress, u_l, A, f, t, pot_local)
727 <                
728 <             endif
729 <          enddo inner
730 <       enddo
731 <      
732 <       point(nrow + 1) = nlist + 1
733 <      
734 <    else  !! (of update_check)
735 <      
736 <       ! use the list to find the neighbors
737 <       do i = 1, nrow
738 <          JBEG = POINT(i)
739 <          JEND = POINT(i+1) - 1
740 <          ! check thiat molecule i has neighbors
741 <          if (jbeg .le. jend) then
742 <            
743 <             do jnab = jbeg, jend
744 <                j = list(jnab)
745 <                
746 <                call get_interatomic_vector(q_Row(:,i), q_Col(:,j), d, rijsq)
747 <                if (SIM_uses_molecular_cutoffs) then
748 <                   call get_interatomic_vector(qcom_Row(:,i), qcom_Col(:,j), &
749 <                        dc, rcijsq)
750 <                else
751 <                   dc(1:3) = d(1:3)
752 <                   rcijsq = rijsq
753 <                endif
754 <                
755 <                call do_pair(i, j, rijsq, d, rcijsq, dc, mfact, &
756 <                     do_pot, do_stress, u_l, A, f, t, pot_local)
757 <                
758 <             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
761 <    endif
762 <    
763 < #else
764 <    
765 <    if (update_nlist) then
766 <      
767 <       ! save current configuration, contruct neighbor list,
768 <       ! and calculate forces
769 <       call saveNeighborList(natoms, q)
770 <      
771 <       neighborListSize = size(list)
772 <      
773 <       nlist = 0
774 <      
775 <       do i = 1, natoms-1
776 <          point(i) = nlist + 1
777 <          
778 <          inner: do j = i+1, natoms
673 >       endif
674              
675 <             if (skipThisPair(i,j))  cycle inner
676 <            
677 <             if (SIM_uses_molecular_cutoffs) then
783 <                call get_interatomic_vector(qcom(:,i), qcom(:,j), &
784 <                     dc, rcijsq)
785 <             else
786 <                call get_interatomic_vector(q(:,i), q(:,j), &
787 <                     dc, rcijsq)
788 <             endif
789 <            
790 <             if (rcijsq < rlistsq) then
791 <                
792 <                nlist = nlist + 1
793 <                
794 <                if (nlist > neighborListSize) then
795 <                   call expandNeighborList(natoms, listerror)
796 <                   if (listerror /= 0) then
797 <                      error = -1
798 <                      write(DEFAULT_ERROR,*) "ERROR: nlist > list size and max allocations exceeded."
799 <                      return
800 <                   end if
801 <                   neighborListSize = size(list)
802 <                endif
803 <                
804 <                list(nlist) = j
805 <                
806 <                if (SIM_uses_molecular_cutoffs) then
807 <                   call get_interatomic_vector(q(:,i), q(:,j), &
808 <                        d, rijsq)
809 <                else
810 <                   d(1:3) = dc(1:3)
811 <                   rijsq = rcijsq
812 <                endif
813 <                
814 <                call do_pair(i, j, rijsq, d, rcijsq, dc, mfact, &
815 <                     do_pot, do_stress, u_l, A, f, t, pot)
816 <                
817 <             endif
818 <          enddo inner
819 <       enddo
675 >       if (loop .eq. PREPAIR_LOOP) then
676 >          call do_preforce(nlocal, pot)
677 >       endif
678        
679 <       point(natoms) = nlist + 1
822 <      
823 <    else !! (update)
824 <      
825 <       ! use the list to find the neighbors
826 <       do i = 1, natoms-1
827 <          JBEG = POINT(i)
828 <          JEND = POINT(i+1) - 1
829 <          ! check thiat molecule i has neighbors
830 <          if (jbeg .le. jend) then
831 <            
832 <             do jnab = jbeg, jend
833 <                j = list(jnab)
834 <
835 <
836 <                call get_interatomic_vector(q(:,i), q(:,j), d, rijsq)
837 <                if (SIM_uses_molecular_cutoffs) then
838 <                   call get_interatomic_vector(qcom(:,i), qcom(:,j), &
839 <                        dc, rcijsq)
840 <                else
841 <                   dc(1:3) = d(1:3)
842 <                   rcijsq = rijsq
843 <                endif
844 <                
845 <                call do_pair(i, j, rijsq, d, rcijsq, dc, mfact, &
846 <                     do_pot, do_stress, u_l, A, f, t, pot)
847 <                
848 <             enddo
849 <          endif
850 <       enddo
851 <    endif
679 >    enddo
680      
853 #endif
854    
855    ! phew, done with main loop.
856    
681      !! Do timing
682   #ifdef PROFILE
683      call cpu_time(forceTimeFinal)
684      forceTime = forceTime + forceTimeFinal - forceTimeInitial
685 < #endif
685 > #endif    
686      
863    
687   #ifdef IS_MPI
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 892 | 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 902 | 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
732 <
732 >      
733      endif
734   #endif
735      
# Line 915 | 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 976 | Line 799 | contains
799      endif
800      
801   #endif
802 <    
980 <    
802 >      
803    end subroutine do_force_loop
804    
805 <  subroutine do_pair(i, j, rijsq, d, rcijsq, dc, mfact, do_pot, do_stress, &
806 <       u_l, A, f, t, pot)
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
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, rcijsq
819 <    real ( kind = dp )                :: r, rc
820 <    real ( kind = dp ), intent(inout) :: d(3), dc(3)
818 >    real ( kind = dp ), intent(inout) :: rijsq
819 >    real ( kind = dp )                :: r
820 >    real ( kind = dp ), intent(inout) :: d(3)
821      integer :: me_i, me_j
822  
823      r = sqrt(rijsq)
824 <    if (SIM_uses_molecular_cutoffs) then
825 <       rc = sqrt(rcijsq)
1003 <    else
1004 <       rc = r
1005 <    endif
824 >    vpair = 0.0d0
825 >    fpair(1:3) = 0.0d0
826  
1007
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 1019 | Line 838 | contains
838      if (FF_uses_LJ .and. SIM_uses_LJ) then
839        
840         if ( PropertyMap(me_i)%is_LJ .and. PropertyMap(me_j)%is_LJ ) then
841 <          call do_lj_pair(i, j, d, r, rijsq, pot, f, do_pot, do_stress)
841 >          !write(*,*) 'calling lj with'
842 >          !write(*,*) i, j, r, rijsq
843 >          !write(*,'(3es12.3)') d(1), d(2), d(3)
844 >          !write(*,'(3es12.3)') sw, vpair, pot
845 >          !write(*,*)
846 >
847 >          call do_lj_pair(i, j, d, r, rijsq, sw, vpair, fpair, pot, f, do_pot)
848         endif
849        
850      endif
# Line 1027 | 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, dc, rc, rcijsq, mfact, &
1031 <               pot, f, do_pot, do_stress, SIM_uses_molecular_cutoffs)
855 >          call do_charge_pair(i, j, d, r, rijsq, sw, vpair, fpair, pot, f, do_pot)
856         endif
857        
858      endif
# Line 1036 | 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, 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)
867 <             call rf_correct_forces(i, j, d, r, u_l, f, do_stress)
866 >             call accumulate_rf(i, j, r, u_l, sw)
867 >             call rf_correct_forces(i, j, d, r, u_l, sw, f, fpair)
868            endif          
869         endif
870  
# Line 1049 | 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, A, pot, 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 1059 | 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, u_l, pot, 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 1068 | 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, pot, f, 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 <
900 >    
901    end subroutine do_pair
902  
903 <
1079 <
1080 <  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 1105 | 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 1118 | 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 <
1132 <
1133 <
954 >
955 >
956   subroutine do_preforce(nlocal,pot)
957     integer :: nlocal
958     real( kind = dp ) :: pot
# Line 1201 | Line 1023 | contains
1023     q_Row = 0.0_dp
1024     q_Col = 0.0_dp
1025  
1026 <   qcom_Row = 0.0_dp
1027 <   qcom_Col = 0.0_dp  
1026 >   q_group_Row = 0.0_dp
1027 >   q_group_Col = 0.0_dp  
1028    
1029     u_l_Row = 0.0_dp
1030     u_l_Col = 0.0_dp
# Line 1255 | 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 1274 | 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 1309 | Line 1131 | contains
1131        endif
1132     enddo
1133    
1134 <   do i = 1, nExcludes_local
1135 <      if (excludesLocal(1,i) == unique_id_1) then
1136 <         if (excludesLocal(2,i) == unique_id_2) then
1137 <            skip_it = .true.
1316 <            return
1317 <         endif
1318 <      else
1319 <         if (excludesLocal(1,i) == unique_id_2) then
1320 <            if (excludesLocal(2,i) == unique_id_1) then
1321 <               skip_it = .true.
1322 <               return
1323 <            endif
1324 <         endif
1134 >   do i = 1, nSkipsForAtom(unique_id_1)
1135 >      if (skipsForAtom(unique_id_1, i) .eq. unique_id_2) then
1136 >         skip_it = .true.
1137 >         return
1138        endif
1139     end do
1140    
# Line 1352 | 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