ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE_old/src/mdtools/libmdCode/lj_FF.F90
Revision: 292
Committed: Thu Mar 6 14:52:44 2003 UTC (21 years, 4 months ago) by chuckv
File size: 8021 byte(s)
Log Message:
Changed code to use one generic force loop. Only one super atype that
has all information is now used.

File Contents

# User Rev Content
1 mmeineke 270 !! Calculates Long Range forces Lennard-Jones interactions.
2     !! Corresponds to the force field defined in lj_FF.cpp
3     !! @author Charles F. Vardeman II
4     !! @author Matthew Meineke
5 chuckv 292 !! @version $Id: lj_FF.F90,v 1.4 2003-03-06 14:52:44 chuckv Exp $, $Date: 2003-03-06 14:52:44 $, $Name: not supported by cvs2svn $, $Revision: 1.4 $
6 mmeineke 270
7    
8    
9     module lj_ff
10     use simulation
11     use definitions
12     use generic_atypes
13 chuckv 288 use neighborLists
14 mmeineke 270 #ifdef IS_MPI
15     use mpiSimulation
16     #endif
17     implicit none
18     PRIVATE
19    
20     !! Logical has lj force field module been initialized?
21     logical, save :: isljFFinit = .false.
22    
23    
24     !! Public methods and data
25     public :: getLjPot
26     public :: init_ljFF
27    
28 chuckv 292 type :: lj_mixed
29     !! Mass of Particle
30     real ( kind = dp ) :: mass = 0.0_dp
31     !! Lennard-Jones epslon
32     real ( kind = dp ) :: epsilon = 0.0_dp
33     !! Lennard-Jones Sigma
34     real ( kind = dp ) :: sigma = 0.0_dp
35     !! Lennard-Jones Sigma Squared
36     real ( kind = dp ) :: sigma2 = 0.0_dp
37     !! Lennard-Jones Sigma to sixth
38     real ( kind = dp ) :: sigma6 = 0.0_dp
39     end type lj_mixed
40 mmeineke 270
41    
42    
43     contains
44    
45 chuckv 292 subroutine init_ljFF(ListHead,status)
46     type (atype),pointer :: ListHead
47     integer :: nTypes
48 mmeineke 270 integer, intent(out) :: status
49    
50 chuckv 292 integer :: myStatus
51 mmeineke 270
52     status = 0
53 chuckv 292 call createMixinList(ListHead,myStatus)
54     if (myStatus /= 0) then
55 mmeineke 270 status = -1
56     return
57     end if
58    
59     end subroutine init_ljFF
60    
61 chuckv 292 subroutine createMixingList(ListHead,status)
62     type (atype), pointer :: ListHead
63 mmeineke 270 integer :: listSize
64     integer :: status
65     integer :: i
66     integer :: j
67    
68     integer :: outerCounter = 0
69     integer :: innerCounter = 0
70 chuckv 292 type (atype), pointer :: tmpPtrOuter => null()
71     type (atype), pointer :: tmpPtrInner => null()
72 mmeineke 270 status = 0
73    
74 chuckv 292 listSize = getListLen(ListHead)
75 mmeineke 270 if (listSize == 0) then
76     status = -1
77     return
78     end if
79    
80    
81     if (.not. associated(ljMixed)) then
82     allocate(ljMixed(listSize,listSize))
83     else
84     status = -1
85     return
86     end if
87    
88    
89    
90     tmpPtrOuter => ljListHead
91     tmpPtrInner => tmpPtrOuter%next
92     do while (associated(tmpPtrOuter))
93     outerCounter = outerCounter + 1
94     ! do self mixing rule
95     ljMixed(outerCounter,outerCounter)%sigma = tmpPtrOuter%sigma
96    
97     ljMixed(outerCounter,outerCounter)%sigma2 = ljMixed(outerCounter,outerCounter)%sigma &
98     * ljMixed(outerCounter,outerCounter)%sigma
99    
100     ljMixed(outerCounter,outerCounter)%sigma6 = ljMixed(outerCounter,outerCounter)%sigma2 &
101     * ljMixed(outerCounter,outerCounter)%sigma2 &
102     * ljMixed(outerCounter,outerCounter)%sigma2
103    
104     ljMixed(outerCounter,outerCounter)%epsilon = tmpPtrOuter%epsilon
105    
106     innerCounter = outerCounter + 1
107     do while (associated(tmpPtrInner))
108    
109     ljMixed(outerCounter,innerCounter)%sigma = &
110     calcLJMix("sigma",tmpPtrOuter%sigma, &
111     tmpPtrInner%sigma)
112    
113     ljMixed(outerCounter,innerCounter)%sigma2 = &
114     ljMixed(outerCounter,innerCounter)%sigma &
115     * ljMixed(outerCounter,innerCounter)%sigma
116    
117     ljMixed(outerCounter,innerCounter)%sigma6 = &
118     ljMixed(outerCounter,innerCounter)%sigma2 &
119     * ljMixed(outerCounter,innerCounter)%sigma2 &
120     * ljMixed(outerCounter,innerCounter)%sigma2
121    
122     ljMixed(outerCounter,innerCounter)%epsilon = &
123     calcLJMix("epsilon",tmpPtrOuter%epsilon, &
124     tmpPtrInner%epsilon)
125     ljMixed(innerCounter,outerCounter)%sigma = ljMixed(outerCounter,innerCounter)%sigma
126     ljMixed(innerCounter,outerCounter)%sigma2 = ljMixed(outerCounter,innerCounter)%sigma2
127     ljMixed(innerCounter,outerCounter)%sigma6 = ljMixed(outerCounter,innerCounter)%sigma6
128     ljMixed(innerCounter,outerCounter)%epsilon = ljMixed(outerCounter,innerCounter)%epsilon
129    
130    
131     tmpPtrInner => tmpPtrInner%next
132     innerCounter = innerCounter + 1
133     end do
134     ! advance pointers
135     tmpPtrOuter => tmpPtrOuter%next
136     if (associated(tmpPtrOuter)) then
137     tmpPtrInner => tmpPtrOuter%next
138     endif
139    
140     end do
141    
142     end subroutine createMixingList
143    
144    
145    
146    
147    
148     !! Calculates the potential between two lj particles based on two lj_atype pointers, optionally returns second
149     !! derivatives.
150     subroutine getLjPot(r,pot,dudr,atype1,atype2,d2,status)
151     ! arguments
152     !! Length of vector between particles
153     real( kind = dp ), intent(in) :: r
154     !! Potential Energy
155     real( kind = dp ), intent(out) :: pot
156     !! Derivatve wrt postion
157     real( kind = dp ), intent(out) :: dudr
158     !! Second Derivative, optional, used mainly for normal mode calculations.
159     real( kind = dp ), intent(out), optional :: d2
160    
161     type (lj_atype), pointer :: atype1
162     type (lj_atype), pointer :: atype2
163    
164     integer, intent(out), optional :: status
165    
166     ! local Variables
167     real( kind = dp ) :: sigma
168     real( kind = dp ) :: sigma2
169     real( kind = dp ) :: sigma6
170     real( kind = dp ) :: epsilon
171    
172     real( kind = dp ) :: rcut
173     real( kind = dp ) :: rcut2
174     real( kind = dp ) :: rcut6
175     real( kind = dp ) :: r2
176     real( kind = dp ) :: r6
177    
178     real( kind = dp ) :: t6
179     real( kind = dp ) :: t12
180     real( kind = dp ) :: tp6
181     real( kind = dp ) :: tp12
182     real( kind = dp ) :: delta
183    
184     logical :: doSec = .false.
185    
186     integer :: errorStat
187    
188     !! Optional Argument Checking
189     ! Check to see if we need to do second derivatives
190    
191     if (present(d2)) doSec = .true.
192     if (present(status)) status = 0
193    
194     ! Look up the correct parameters in the mixing matrix
195     sigma = ljMixed(atype1%atype_ident,atype2%atype_ident)%sigma
196     sigma2 = ljMixed(atype1%atype_ident,atype2%atype_ident)%sigma2
197     sigma6 = ljMixed(atype1%atype_ident,atype2%atype_ident)%sigma6
198     epsilon = ljMixed(atype1%atype_ident,atype2%atype_ident)%epsilon
199    
200    
201    
202    
203     call getRcut(rcut,rcut2=rcut2,rcut6=rcut6,status=errorStat)
204    
205     r2 = r * r
206     r6 = r2 * r2 * r2
207    
208     t6 = sigma6/ r6
209     t12 = t6 * t6
210    
211    
212    
213     tp6 = sigma6 / rcut6
214     tp12 = tp6*tp6
215    
216     delta = -4.0E0_DP*epsilon * (tp12 - tp6)
217    
218     if (r.le.rcut) then
219     pot = 4.0E0_DP * epsilon * (t12 - t6) + delta
220     dudr = 24.0E0_DP * epsilon * (t6 - 2.0E0_DP*t12) / r
221     if(doSec) d2 = 24.0E0_DP * epsilon * (26.0E0_DP*t12 - 7.0E0_DP*t6)/r/r
222     else
223     pot = 0.0E0_DP
224     dudr = 0.0E0_DP
225     if(doSec) d2 = 0.0E0_DP
226     endif
227    
228     return
229    
230    
231    
232     end subroutine getLjPot
233    
234    
235     !! Calculates the mixing for sigma or epslon based on character string for initialzition of mixing array.
236     function calcLJMix(thisParam,param1,param2,status) result(myMixParam)
237     character(len=*) :: thisParam
238     real(kind = dp) :: param1
239     real(kind = dp) :: param2
240     real(kind = dp ) :: myMixParam
241 mmeineke 285 character(len = getStringLen()) :: thisMixingRule
242 mmeineke 270 integer, optional :: status
243    
244 mmeineke 285 !! get the mixing rules from the simulation
245     thisMixingRule = returnMixingRules()
246 mmeineke 270 myMixParam = 0.0_dp
247    
248     if (present(status)) status = 0
249 mmeineke 285 select case (thisMixingRule)
250     case ("standard")
251     select case (thisParam)
252     case ("sigma")
253     myMixParam = 0.5_dp * (param1 + param2)
254     case ("epsilon")
255     myMixParam = sqrt(param1 * param2)
256     case default
257     status = -1
258     end select
259     case("LJglass")
260 mmeineke 270 case default
261     status = -1
262     end select
263     end function calcLJMix
264    
265    
266    
267     end module lj_ff