4 |
|
|
5 |
|
!! @author Charles F. Vardeman II |
6 |
|
!! @author Matthew Meineke |
7 |
< |
!! @version $Id: do_Forces.F90,v 1.18 2003-03-13 15:28:43 gezelter Exp $, $Date: 2003-03-13 15:28:43 $, $Name: not supported by cvs2svn $, $Revision: 1.18 $ |
7 |
> |
!! @version $Id: do_Forces.F90,v 1.19 2003-03-13 17:45:54 gezelter Exp $, $Date: 2003-03-13 17:45:54 $, $Name: not supported by cvs2svn $, $Revision: 1.19 $ |
8 |
|
|
9 |
|
|
10 |
|
|
212 |
|
|
213 |
|
!! save current configuration, construct neighbor list, |
214 |
|
!! and calculate forces |
215 |
< |
call save_neighborList(q) |
215 |
> |
call saveNeighborList(q) |
216 |
|
|
217 |
|
neighborListSize = getNeighborListSize() |
218 |
|
nlist = 0 |
222 |
|
|
223 |
|
inner: do j = 1, ncol |
224 |
|
|
225 |
< |
if (checkExcludes(i,j)) cycle inner |
225 |
> |
if (skipThisPair(i,j)) cycle inner |
226 |
|
|
227 |
|
call get_interatomic_vector(q_Row(:,i), q_Col(:,j), d, rijsq) |
228 |
|
|
276 |
|
|
277 |
|
! save current configuration, contruct neighbor list, |
278 |
|
! and calculate forces |
279 |
< |
call save_neighborList(q) |
279 |
> |
call saveNeighborList(q) |
280 |
|
|
281 |
|
neighborListSize = getNeighborListSize() |
282 |
|
nlist = 0 |
286 |
|
|
287 |
|
inner: do j = i+1, natoms |
288 |
|
|
289 |
< |
if (checkExcludes(i,j)) cycle inner |
289 |
> |
if (skipThisPair(i,j)) cycle inner |
290 |
|
|
291 |
|
call get_interatomic_vector(q(:,i), q(:,j), d, rijsq) |
292 |
|
|
595 |
|
|
596 |
|
end subroutine zero_work_arrays |
597 |
|
|
598 |
< |
|
599 |
< |
!! Function to properly build neighbor lists in MPI using newtons 3rd law. |
600 |
< |
!! We don't want 2 processors doing the same i j pair twice. |
601 |
< |
!! Also checks to see if i and j are the same particle. |
602 |
< |
|
603 |
< |
function checkExcludes(atom1,atom2) result(do_cycle) |
598 |
> |
function skipThisPair(atom1, atom2) result(skip_it) |
599 |
|
|
600 |
< |
integer,intent(in) :: atom1 |
601 |
< |
integer,intent(in), optional :: atom2 |
602 |
< |
logical :: do_cycle |
603 |
< |
integer :: unique_id_1, unique_id_2 |
604 |
< |
integer :: i, j |
600 |
> |
integer, intent(in) :: atom1 |
601 |
> |
integer, intent(in), optional :: atom2 |
602 |
> |
logical :: skip_it |
603 |
> |
integer :: unique_id_1, unique_id_2 |
604 |
> |
integer :: i |
605 |
|
|
606 |
< |
do_cycle = .false. |
606 |
> |
skip_it = .false. |
607 |
> |
|
608 |
> |
!! there are a number of reasons to skip a pair or a particle |
609 |
> |
!! mostly we do this to exclude atoms who are involved in short |
610 |
> |
!! range interactions (bonds, bends, torsions), but we also need |
611 |
> |
!! to exclude some overcounted interactions that result from |
612 |
> |
!! the parallel decomposition |
613 |
|
|
614 |
|
#ifdef IS_MPI |
615 |
+ |
!! in MPI, we have to look up the unique IDs for each atom |
616 |
|
unique_id_1 = tagRow(atom1) |
617 |
|
#else |
618 |
< |
unique_id_1 = tag(atom1) |
618 |
> |
!! in the normal loop, the atom numbers are unique |
619 |
> |
unique_id_1 = atom1 |
620 |
|
#endif |
621 |
|
|
622 |
< |
!! Check global excludes first |
622 |
> |
!! We were called with only one atom, so just check the global exclude |
623 |
> |
!! list for this atom |
624 |
|
if (.not. present(atom2)) then |
625 |
|
do i = 1, nExcludes_global |
626 |
|
if (excludesGlobal(i) == unique_id_1) then |
627 |
< |
do_cycle = .true. |
627 |
> |
skip_it = .true. |
628 |
|
return |
629 |
|
end if |
630 |
|
end do |
631 |
< |
return !! return after checking globals |
631 |
> |
return |
632 |
|
end if |
629 |
– |
|
630 |
– |
!! we return if atom2 not present here. |
633 |
|
|
634 |
|
#ifdef IS_MPI |
635 |
|
unique_id_2 = tagColumn(atom2) |
636 |
|
#else |
637 |
< |
unique_id_2 = tag(atom2) |
637 |
> |
unique_id_2 = atom2 |
638 |
|
#endif |
639 |
|
|
640 |
+ |
#ifdef IS_MPI |
641 |
+ |
!! this situation should only arise in MPI simulations |
642 |
|
if (unique_id_1 == unique_id_2) then |
643 |
< |
do_cycle = .true. |
643 |
> |
skip_it = .true. |
644 |
|
return |
645 |
|
end if |
646 |
|
|
647 |
+ |
!! this prevents us from doing the pair on multiple processors |
648 |
|
if (unique_id_1 < unique_id_2) then |
649 |
< |
if (mod(unique_id_1 + unique_id_2,2) == 0) do_cycle = .true. |
649 |
> |
if (mod(unique_id_1 + unique_id_2,2) == 0) skip_it = .true. |
650 |
|
return |
651 |
|
else |
652 |
< |
if (mod(unique_id_1 + unique_id_2,2) == 1) do_cycle = .true. |
652 |
> |
if (mod(unique_id_1 + unique_id_2,2) == 1) skip_it = .true. |
653 |
|
endif |
654 |
+ |
#endif |
655 |
+ |
|
656 |
+ |
!! the rest of these situations can happen in all simulations: |
657 |
+ |
do i = 1, nExcludes_global |
658 |
+ |
if ((excludesGlobal(i) == unique_id_1) .or. & |
659 |
+ |
(excludesGlobal(i) == unique_id_2)) then |
660 |
+ |
skip_it = .true. |
661 |
+ |
return |
662 |
+ |
endif |
663 |
+ |
enddo |
664 |
|
|
665 |
|
do i = 1, nExcludes_local |
666 |
< |
if ((unique_id_1 == excludesLocal(1,i)) .and. & |
667 |
< |
(excludesLocal(2,i) < 0)) then |
668 |
< |
do_cycle = .true. |
669 |
< |
return |
670 |
< |
end if |
666 |
> |
if (excludesLocal(1,i) == unique_id_1) then |
667 |
> |
if (excludesLocal(2,i) == unique_id_2) then |
668 |
> |
skip_it = .true. |
669 |
> |
return |
670 |
> |
endif |
671 |
> |
else |
672 |
> |
if (excludesLocal(1,i) == unique_id_2) then |
673 |
> |
if (excludesLocal(2,i) == unique_id_1) then |
674 |
> |
skip_it = .true. |
675 |
> |
return |
676 |
> |
endif |
677 |
> |
endif |
678 |
> |
endif |
679 |
|
end do |
680 |
|
|
681 |
< |
end function checkExcludes |
681 |
> |
return |
682 |
> |
end function skipThisPair |
683 |
|
|
684 |
|
function FF_UsesDirectionalAtoms() result(doesit) |
685 |
|
logical :: doesit |