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 438 by chuckv, Mon Mar 31 21:50:59 2003 UTC vs.
Revision 648 by chuckv, Wed Jul 23 22:13:59 2003 UTC

# Line 4 | Line 4
4  
5   !! @author Charles F. Vardeman II
6   !! @author Matthew Meineke
7 < !! @version $Id: do_Forces.F90,v 1.5 2003-03-31 21:50:59 chuckv Exp $, $Date: 2003-03-31 21:50:59 $, $Name: not supported by cvs2svn $, $Revision: 1.5 $
7 > !! @version $Id: do_Forces.F90,v 1.24 2003-07-23 22:13:59 chuckv Exp $, $Date: 2003-07-23 22:13:59 $, $Name: not supported by cvs2svn $, $Revision: 1.24 $
8  
9   module do_Forces
10    use force_globals
# Line 17 | Line 17 | module do_Forces
17    use dipole_dipole
18    use reaction_field
19    use gb_pair
20 +  use vector_class
21   #ifdef IS_MPI
22    use mpiSimulation
23   #endif
# Line 27 | Line 28 | module do_Forces
28   #define __FORTRAN90
29   #include "fForceField.h"
30  
31 <  logical, save :: do_forces_initialized = .false.
31 >  logical, save :: do_forces_initialized = .false., haveRlist = .false.
32 >  logical, save :: havePolicies = .false.
33    logical, save :: FF_uses_LJ
34    logical, save :: FF_uses_sticky
35    logical, save :: FF_uses_dipoles
# Line 35 | Line 37 | module do_Forces
37    logical, save :: FF_uses_GB
38    logical, save :: FF_uses_EAM
39  
40 +  real(kind=dp), save :: rlist, rlistsq
41 +
42    public :: init_FF
43    public :: do_force_loop
44 +  public :: setRlistDF
45  
46   contains
47  
48 +  subroutine setRlistDF( this_rlist )
49 +    
50 +    real(kind=dp) :: this_rlist
51 +
52 +    rlist = this_rlist
53 +    rlistsq = rlist * rlist
54 +    
55 +    haveRlist = .true.
56 +    if( havePolicies ) do_forces_initialized = .true.
57 +
58 +  end subroutine setRlistDF    
59 +
60    subroutine init_FF(LJMIXPOLICY, use_RF_c, thisStat)
61  
62      integer, intent(in) :: LJMIXPOLICY
# Line 87 | Line 104 | contains
104      !! check to make sure the FF_uses_RF setting makes sense
105      
106      if (FF_uses_dipoles) then
90       rrf = getRrf()
91       rt = getRt()      
92       call initialize_dipole(rrf, rt)
107         if (FF_uses_RF) then
108            dielect = getDielect()
109 <          call initialize_rf(rrf, rt, dielect)
109 >          call initialize_rf(dielect)
110         endif
111      else
112         if (FF_uses_RF) then          
# Line 100 | Line 114 | contains
114            thisStat = -1
115            return
116         endif
117 <    endif
117 >    endif
118  
119      if (FF_uses_LJ) then
120        
107       call getRcut(rcut)
108
121         select case (LJMIXPOLICY)
122         case (LB_MIXING_RULE)
123 <          call init_lj_FF(LB_MIXING_RULE, rcut, my_status)            
123 >          call init_lj_FF(LB_MIXING_RULE, my_status)            
124         case (EXPLICIT_MIXING_RULE)
125 <          call init_lj_FF(EXPLICIT_MIXING_RULE, rcut, my_status)
125 >          call init_lj_FF(EXPLICIT_MIXING_RULE, my_status)
126         case default
127            write(default_error,*) 'unknown LJ Mixing Policy!'
128            thisStat = -1
# Line 140 | Line 152 | contains
152  
153      if (FF_uses_GB .and. FF_uses_LJ) then
154      endif
155 +    if (.not. do_forces_initialized) then
156 +       !! Create neighbor lists
157 +       call expandNeighborList(getNlocal(), my_status)
158 +       if (my_Status /= 0) then
159 +          write(default_error,*) "SimSetup: ExpandNeighborList returned error."
160 +          thisStat = -1
161 +          return
162 +       endif
163 +    endif
164  
165 <
166 <    do_forces_initialized = .true.    
167 <
165 >    havePolicies = .true.
166 >    if( haveRlist ) do_forces_initialized = .true.
167 >    
168    end subroutine init_FF
169    
170  
# Line 167 | Line 188 | contains
188      logical ( kind = 2) :: do_pot_c, do_stress_c
189      logical :: do_pot
190      logical :: do_stress
191 < #ifdef IS_MPI
191 > #ifdef IS_MPI
192      real( kind = DP ) :: pot_local
193      integer :: nrow
194      integer :: ncol
# Line 177 | Line 198 | contains
198      logical :: update_nlist  
199      integer :: i, j, jbeg, jend, jnab
200      integer :: nlist
201 <    real( kind = DP ) ::  rijsq, rlistsq, rcutsq, rlist, rcut
201 >    real( kind = DP ) ::  rijsq
202      real(kind=dp),dimension(3) :: d
203      real(kind=dp) :: rfpot, mu_i, virial
204      integer :: me_i
# Line 186 | Line 207 | contains
207      integer :: listerror, error
208      integer :: localError
209  
210 +    real(kind=dp) :: listSkin = 1.0
211 +    
212 +
213      !! initialize local variables  
214  
215   #ifdef IS_MPI
216 +    pot_local = 0.0_dp
217      nlocal = getNlocal()
218      nrow   = getNrow(plan_row)
219      ncol   = getNcol(plan_col)
# Line 196 | Line 221 | contains
221      nlocal = getNlocal()
222      natoms = nlocal
223   #endif
224 <
200 <    call getRcut(rcut,rc2=rcutsq)
201 <    call getRlist(rlist,rlistsq)
202 <    
224 >  
225      call check_initialization(localError)
226      if ( localError .ne. 0 ) then
227         error = -1
# Line 229 | Line 251 | contains
251      
252      if (FF_RequiresPrepairCalc() .and. SimRequiresPrepairCalc()) then
253         !! See if we need to update neighbor lists
254 <       call checkNeighborList(nlocal, q, rcut, rlist, update_nlist)  
254 >       call checkNeighborList(nlocal, q, listSkin, update_nlist)  
255         !! if_mpi_gather_stuff_for_prepair
256         !! do_prepair_loop_if_needed
257         !! if_mpi_scatter_stuff_from_prepair
258         !! if_mpi_gather_stuff_from_prepair_to_main_loop
259 <    else
260 <       !! See if we need to update neighbor lists
261 <       call checkNeighborList(nlocal, q, rcut, rlist, update_nlist)  
259 >
260 > !--------------------PREFORCE LOOP----------->>>>>>>>>>>>>>>>>>>>>>>>>>>
261 > #ifdef IS_MPI
262 >    
263 >    if (update_nlist) then
264 >      
265 >       !! save current configuration, construct neighbor list,
266 >       !! and calculate forces
267 >       call saveNeighborList(nlocal, q)
268 >      
269 >       neighborListSize = size(list)
270 >       nlist = 0      
271 >      
272 >       do i = 1, nrow
273 >          point(i) = nlist + 1
274 >          
275 >          prepair_inner: do j = 1, ncol
276 >            
277 >             if (skipThisPair(i,j)) cycle prepair_inner
278 >            
279 >             call get_interatomic_vector(q_Row(:,i), q_Col(:,j), d, rijsq)
280 >            
281 >             if (rijsq < rlistsq) then            
282 >                
283 >                nlist = nlist + 1
284 >                
285 >                if (nlist > neighborListSize) then
286 >                   call expandNeighborList(nlocal, listerror)
287 >                   if (listerror /= 0) then
288 >                      error = -1
289 >                      write(DEFAULT_ERROR,*) "ERROR: nlist > list size and max allocations exceeded."
290 >                      return
291 >                   end if
292 >                   neighborListSize = size(list)
293 >                endif
294 >                
295 >                list(nlist) = j
296 >                call do_prepair(i, j, rijsq, d, do_pot, do_stress, u_l, A, f, t, pot_local)                      
297 >             endif
298 >          enddo prepair_inner
299 >       enddo
300 >
301 >       point(nrow + 1) = nlist + 1
302 >      
303 >    else  !! (of update_check)
304 >
305 >       ! use the list to find the neighbors
306 >       do i = 1, nrow
307 >          JBEG = POINT(i)
308 >          JEND = POINT(i+1) - 1
309 >          ! check thiat molecule i has neighbors
310 >          if (jbeg .le. jend) then
311 >            
312 >             do jnab = jbeg, jend
313 >                j = list(jnab)
314 >
315 >                call get_interatomic_vector(q_Row(:,i), q_Col(:,j), d, rijsq)
316 >                call do_prepair(i, j, rijsq, d, do_pot, do_stress, &
317 >                     u_l, A, f, t, pot_local)
318 >
319 >             enddo
320 >          endif
321 >       enddo
322      endif
323      
324 + #else
325 +    
326 +    if (update_nlist) then
327 +      
328 +       ! save current configuration, contruct neighbor list,
329 +       ! and calculate forces
330 +       call saveNeighborList(natoms, q)
331 +      
332 +       neighborListSize = size(list)
333 +  
334 +       nlist = 0
335 +      
336 +       do i = 1, natoms-1
337 +          point(i) = nlist + 1
338 +          
339 +          prepair_inner: do j = i+1, natoms
340 +            
341 +             if (skipThisPair(i,j))  cycle prepair_inner
342 +                          
343 +             call get_interatomic_vector(q(:,i), q(:,j), d, rijsq)
344 +          
345 +
346 +             if (rijsq < rlistsq) then
347 +                
348 +                nlist = nlist + 1
349 +              
350 +                if (nlist > neighborListSize) then
351 +                   call expandNeighborList(natoms, listerror)
352 +                   if (listerror /= 0) then
353 +                      error = -1
354 +                      write(DEFAULT_ERROR,*) "ERROR: nlist > list size and max allocations exceeded."
355 +                      return
356 +                   end if
357 +                   neighborListSize = size(list)
358 +                endif
359 +                
360 +                list(nlist) = j
361 +                
362 +                call do_prepair(i, j, rijsq, d, do_pot, do_stress, &
363 +                        u_l, A, f, t, pot)
364 +                
365 +             endif
366 +          enddo prepair_inner
367 +       enddo
368 +      
369 +       point(natoms) = nlist + 1
370 +      
371 +    else !! (update)
372 +      
373 +       ! use the list to find the neighbors
374 +       do i = 1, natoms-1
375 +          JBEG = POINT(i)
376 +          JEND = POINT(i+1) - 1
377 +          ! check thiat molecule i has neighbors
378 +          if (jbeg .le. jend) then
379 +            
380 +             do jnab = jbeg, jend
381 +                j = list(jnab)
382 +
383 +                call get_interatomic_vector(q(:,i), q(:,j), d, rijsq)
384 +                call do_prepair(i, j, rijsq, d, do_pot, do_stress, &
385 +                     u_l, A, f, t, pot)
386 +
387 +             enddo
388 +          endif
389 +       enddo
390 +    endif    
391 + #endif
392 +    !! Do rest of preforce calculations
393 +   call do_preforce(nlocal,pot)
394 +    else
395 +       !! See if we need to update neighbor lists for non pre-pair
396 +       call checkNeighborList(nlocal, q, listSkin, update_nlist)  
397 +    endif
398 +
399 +
400 +
401 +
402 +
403 + !---------------------------------MAIN Pair LOOP->>>>>>>>>>>>>>>>>>>>>>>>>>>>
404 +
405 +
406 +
407 +
408 +  
409   #ifdef IS_MPI
410      
411      if (update_nlist) then
412        
413         !! save current configuration, construct neighbor list,
414         !! and calculate forces
415 <       call saveNeighborList(q)
415 >       call saveNeighborList(nlocal, q)
416        
417         neighborListSize = size(list)
418         nlist = 0      
# Line 259 | Line 426 | contains
426              
427               call get_interatomic_vector(q_Row(:,i), q_Col(:,j), d, rijsq)
428              
429 <             if (rijsq <  rlistsq) then            
429 >             if (rijsq < rlistsq) then            
430                  
431                  nlist = nlist + 1
432                  
# Line 275 | Line 442 | contains
442                  
443                  list(nlist) = j
444                                  
445 <                if (rijsq <  rcutsq) then
446 <                   call do_pair(i, j, rijsq, d, do_pot, do_stress, &
447 <                        u_l, A, f, t,pot)
281 <                endif
445 >                call do_pair(i, j, rijsq, d, do_pot, do_stress, &
446 >                     u_l, A, f, t, pot_local)
447 >                
448               endif
449            enddo inner
450         enddo
# Line 299 | Line 465 | contains
465  
466                  call get_interatomic_vector(q_Row(:,i), q_Col(:,j), d, rijsq)
467                  call do_pair(i, j, rijsq, d, do_pot, do_stress, &
468 <                     u_l, A, f, t,pot)
468 >                     u_l, A, f, t, pot_local)
469  
470               enddo
471            endif
# Line 312 | Line 478 | contains
478        
479         ! save current configuration, contruct neighbor list,
480         ! and calculate forces
481 <       call saveNeighborList(q)
481 >       call saveNeighborList(natoms, q)
482        
483         neighborListSize = size(list)
484    
# Line 328 | Line 494 | contains
494               call get_interatomic_vector(q(:,i), q(:,j), d, rijsq)
495            
496  
497 <             if (rijsq <  rlistsq) then
497 >             if (rijsq < rlistsq) then
498                  
499                  nlist = nlist + 1
500                
# Line 344 | Line 510 | contains
510                  
511                  list(nlist) = j
512                  
513 <                if (rijsq <  rcutsq) then
514 <                   call do_pair(i, j, rijsq, d, do_pot, do_stress, &
515 <                        u_l, A, f, t,pot)
350 <                endif
513 >                call do_pair(i, j, rijsq, d, do_pot, do_stress, &
514 >                        u_l, A, f, t, pot)
515 >                
516               endif
517            enddo inner
518         enddo
# Line 368 | Line 533 | contains
533  
534                  call get_interatomic_vector(q(:,i), q(:,j), d, rijsq)
535                  call do_pair(i, j, rijsq, d, do_pot, do_stress, &
536 <                     u_l, A, f, t,pot)
536 >                     u_l, A, f, t, pot)
537  
538               enddo
539            endif
# Line 411 | Line 576 | contains
576      if (do_pot) then
577         ! scatter/gather pot_row into the members of my column
578         call scatter(pot_Row, pot_Temp, plan_row)
579 <      
579 >
580         ! scatter/gather pot_local into all other procs
581         ! add resultant to get total pot
582         do i = 1, nlocal
583            pot_local = pot_local + pot_Temp(i)
584         enddo
585 +      
586 +       pot_Temp = 0.0_DP
587  
421       pot_Temp = 0.0_DP
422
588         call scatter(pot_Col, pot_Temp, plan_col)
589         do i = 1, nlocal
590            pot_local = pot_local + pot_Temp(i)
591         enddo
592 <      
592 >
593      endif    
594   #endif
595  
# Line 472 | Line 637 | contains
637   #ifdef IS_MPI
638  
639      if (do_pot) then
640 <       write(*,*) "Fortran is on pot:, pot, pot_local ", pot,pot_local
476 <       pot = pot_local
640 >       pot = pot + pot_local
641         !! we assume the c code will do the allreduce to get the total potential
642         !! we could do it right here if we needed to...
643      endif
644  
645      if (do_stress) then
646 <       call mpi_allreduce(tau, tau_Temp,9,mpi_double_precision,mpi_sum, &
646 >      call mpi_allreduce(tau_Temp, tau, 9,mpi_double_precision,mpi_sum, &
647              mpi_comm_world,mpi_err)
648 <       call mpi_allreduce(virial, virial_Temp,1,mpi_double_precision,mpi_sum, &
648 >       call mpi_allreduce(virial_Temp, virial,1,mpi_double_precision,mpi_sum, &
649              mpi_comm_world,mpi_err)
650      endif
651  
# Line 496 | Line 660 | contains
660      
661    end subroutine do_force_loop
662  
663 <  subroutine do_pair(i, j, rijsq, d, do_pot, do_stress, u_l, A, f, t,pot)
663 >  subroutine do_pair(i, j, rijsq, d, do_pot, do_stress, u_l, A, f, t, pot)
664  
665      real( kind = dp ) :: pot
666 <    real( kind = dp ), dimension(:,:) :: u_l
667 <    real (kind=dp), dimension(:,:) :: A
668 <    real (kind=dp), dimension(:,:) :: f
669 <    real (kind=dp), dimension(:,:) :: t
666 >    real( kind = dp ), dimension(3,getNlocal()) :: u_l
667 >    real (kind=dp), dimension(9,getNlocal()) :: A
668 >    real (kind=dp), dimension(3,getNlocal()) :: f
669 >    real (kind=dp), dimension(3,getNlocal()) :: t
670  
671      logical, intent(inout) :: do_pot, do_stress
672      integer, intent(in) :: i, j
# Line 512 | Line 676 | contains
676      logical :: is_LJ_i, is_LJ_j
677      logical :: is_DP_i, is_DP_j
678      logical :: is_GB_i, is_GB_j
679 +    logical :: is_EAM_i,is_EAM_j
680      logical :: is_Sticky_i, is_Sticky_j
681      integer :: me_i, me_j
682  
683      r = sqrt(rijsq)
684  
685   #ifdef IS_MPI
686 +    if (tagRow(i) .eq. tagColumn(j)) then
687 +       write(0,*) 'do_pair is doing', i , j, tagRow(i), tagColumn(j)
688 +    endif
689  
690      me_i = atid_row(i)
691      me_j = atid_col(j)
# Line 576 | Line 744 | contains
744         endif
745      endif
746      
747 +
748 +  
749 +   if (FF_uses_EAM .and. SimUsesEAM()) then
750 +      call getElementProperty(atypes, me_i, "is_EAM", is_EAM_i)
751 +      call getElementProperty(atypes, me_j, "is_EAM", is_EAM_j)
752 +      
753 +      if ( is_EAM_i .and. is_EAM_j ) &
754 +           call do_eam_pair(i, j, d, r, rijsq, pot, f, do_pot, do_stress)
755 +   endif
756 +
757 +
758 +
759 +
760    end subroutine do_pair
761 +
762 +
763 +
764 +  subroutine do_prepair(i, j, rijsq, d, do_pot, do_stress, u_l, A, f, t, pot)
765 +   real( kind = dp ) :: pot
766 +   real( kind = dp ), dimension(3,getNlocal()) :: u_l
767 +   real (kind=dp), dimension(9,getNlocal()) :: A
768 +   real (kind=dp), dimension(3,getNlocal()) :: f
769 +   real (kind=dp), dimension(3,getNlocal()) :: t
770 +  
771 +   logical, intent(inout) :: do_pot, do_stress
772 +   integer, intent(in) :: i, j
773 +   real ( kind = dp ), intent(inout)    :: rijsq
774 +   real ( kind = dp )                :: r
775 +   real ( kind = dp ), intent(inout) :: d(3)
776 +  
777 +   logical :: is_EAM_i, is_EAM_j
778 +  
779 +   integer :: me_i, me_j
780 +  
781 +   r = sqrt(rijsq)
782 +  
783 + #ifdef IS_MPI
784 +   if (tagRow(i) .eq. tagColumn(j)) then
785 +      write(0,*) 'do_pair is doing', i , j, tagRow(i), tagColumn(j)
786 +   endif
787 +  
788 +   me_i = atid_row(i)
789 +   me_j = atid_col(j)
790 +  
791 + #else
792 +  
793 +   me_i = atid(i)
794 +   me_j = atid(j)
795 +  
796 + #endif
797 +  
798 +   if (FF_uses_EAM .and. SimUsesEAM()) then
799 +      call getElementProperty(atypes, me_i, "is_EAM", is_EAM_i)
800 +      call getElementProperty(atypes, me_j, "is_EAM", is_EAM_j)
801 +      
802 +      if ( is_EAM_i .and. is_EAM_j ) &
803 +           call calc_EAM_prepair_rho(i, j, d, r, rijsq )
804 +   endif
805 +  end subroutine do_prepair
806  
807  
808 +
809 +
810 +  subroutine do_preforce(nlocal,pot)
811 +    integer :: nlocal
812 +    real( kind = dp ) :: pot
813 +
814 +   if (FF_uses_EAM .and. SimUsesEAM()) then
815 +      call calc_EAM_preforce_Frho(nlocal,pot)
816 +   endif
817 +
818 +
819 +  end subroutine do_preforce
820 +  
821 +  
822    subroutine get_interatomic_vector(q_i, q_j, d, r_sq)
823      
824      real (kind = dp), dimension(3) :: q_i
825      real (kind = dp), dimension(3) :: q_j
826      real ( kind = dp ), intent(out) :: r_sq
827 <    real( kind = dp ) :: d(3)
828 <    real( kind = dp ) :: d_old(3)
829 <    d(1:3) = q_i(1:3) - q_j(1:3)
830 <    d_old = d
827 >    real( kind = dp ) :: d(3), scaled(3)
828 >    integer i
829 >
830 >    d(1:3) = q_j(1:3) - q_i(1:3)
831 >
832      ! Wrap back into periodic box if necessary
833      if ( SimUsesPBC() ) then
834        
835 <       d(1:3) = d(1:3) - box(1:3) * sign(1.0_dp,d(1:3)) * &
836 <            int(abs(d(1:3)/box(1:3)) + 0.5_dp)
835 >       if( .not.boxIsOrthorhombic ) then
836 >          ! calc the scaled coordinates.
837 >          
838 >          scaled = matmul(HmatInv, d)
839 >          
840 >          ! wrap the scaled coordinates
841 >
842 >          scaled = scaled  - anint(scaled)
843 >          
844 >
845 >          ! calc the wrapped real coordinates from the wrapped scaled
846 >          ! coordinates
847 >
848 >          d = matmul(Hmat,scaled)
849 >
850 >       else
851 >          ! calc the scaled coordinates.
852 >          
853 >          do i = 1, 3
854 >             scaled(i) = d(i) * HmatInv(i,i)
855 >            
856 >             ! wrap the scaled coordinates
857 >            
858 >             scaled(i) = scaled(i) - anint(scaled(i))
859 >            
860 >             ! calc the wrapped real coordinates from the wrapped scaled
861 >             ! coordinates
862 >
863 >             d(i) = scaled(i)*Hmat(i,i)
864 >          enddo
865 >       endif
866        
867      endif
868 +    
869      r_sq = dot_product(d,d)
870 <        
870 >    
871    end subroutine get_interatomic_vector
872 <
872 >  
873    subroutine check_initialization(error)
874      integer, intent(out) :: error
875      
# Line 655 | Line 926 | contains
926      rf = 0.0_dp
927      tau_Temp = 0.0_dp
928      virial_Temp = 0.0_dp
658    
929    end subroutine zero_work_arrays
930    
931    function skipThisPair(atom1, atom2) result(skip_it)
# Line 699 | Line 969 | contains
969   #else
970      unique_id_2 = atom2
971   #endif
972 <    
972 >
973   #ifdef IS_MPI
974      !! this situation should only arise in MPI simulations
975      if (unique_id_1 == unique_id_2) then
# Line 709 | Line 979 | contains
979      
980      !! this prevents us from doing the pair on multiple processors
981      if (unique_id_1 < unique_id_2) then
982 <       if (mod(unique_id_1 + unique_id_2,2) == 0) skip_it = .true.
983 <       return
982 >       if (mod(unique_id_1 + unique_id_2,2) == 0) then
983 >          skip_it = .true.
984 >          return
985 >       endif
986      else                
987 <       if (mod(unique_id_1 + unique_id_2,2) == 1) skip_it = .true.
988 <       return
987 >       if (mod(unique_id_1 + unique_id_2,2) == 1) then
988 >          skip_it = .true.
989 >          return
990 >       endif
991      endif
992   #endif
993 <
993 >
994      !! the rest of these situations can happen in all simulations:
995      do i = 1, nExcludes_global      
996         if ((excludesGlobal(i) == unique_id_1) .or. &
# Line 725 | Line 999 | contains
999            return
1000         endif
1001      enddo
1002 <
1002 >
1003      do i = 1, nExcludes_local
1004         if (excludesLocal(1,i) == unique_id_1) then
1005            if (excludesLocal(2,i) == unique_id_2) then

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines