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

# Content
1 !! 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 !! @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
7
8
9 module lj_ff
10 use simulation
11 use definitions
12 use generic_atypes
13 use neighborLists
14 #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 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
41
42
43 contains
44
45 subroutine init_ljFF(ListHead,status)
46 type (atype),pointer :: ListHead
47 integer :: nTypes
48 integer, intent(out) :: status
49
50 integer :: myStatus
51
52 status = 0
53 call createMixinList(ListHead,myStatus)
54 if (myStatus /= 0) then
55 status = -1
56 return
57 end if
58
59 end subroutine init_ljFF
60
61 subroutine createMixingList(ListHead,status)
62 type (atype), pointer :: ListHead
63 integer :: listSize
64 integer :: status
65 integer :: i
66 integer :: j
67
68 integer :: outerCounter = 0
69 integer :: innerCounter = 0
70 type (atype), pointer :: tmpPtrOuter => null()
71 type (atype), pointer :: tmpPtrInner => null()
72 status = 0
73
74 listSize = getListLen(ListHead)
75 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 character(len = getStringLen()) :: thisMixingRule
242 integer, optional :: status
243
244 !! get the mixing rules from the simulation
245 thisMixingRule = returnMixingRules()
246 myMixParam = 0.0_dp
247
248 if (present(status)) status = 0
249 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 case default
261 status = -1
262 end select
263 end function calcLJMix
264
265
266
267 end module lj_ff