ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE_old/src/mdtools/libmdCode/calc_LJ_FF.F90
Revision: 298
Committed: Fri Mar 7 18:26:30 2003 UTC (21 years, 4 months ago) by chuckv
File size: 7838 byte(s)
Log Message:
More code clean-up.

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: calc_LJ_FF.F90,v 1.1 2003-03-07 18:26:30 chuckv Exp $, $Date: 2003-03-07 18:26:30 $, $Name: not supported by cvs2svn $, $Revision: 1.1 $
6
7
8
9 module lj_ff
10 use simulation
11 use definitions
12 use generic_atypes
13
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)**2
115
116 ljMixed(outerCounter,innerCounter)%sigma6 = &
117 (ljMixed(outerCounter,innerCounter)%sigma)**6
118
119 ljMixed(outerCounter,innerCounter)%epsilon = &
120 calcLJMix("epsilon",tmpPtrOuter%epsilon, &
121 tmpPtrInner%epsilon)
122 ljMixed(innerCounter,outerCounter)%sigma = ljMixed(outerCounter,innerCounter)%sigma
123 ljMixed(innerCounter,outerCounter)%sigma2 = ljMixed(outerCounter,innerCounter)%sigma2
124 ljMixed(innerCounter,outerCounter)%sigma6 = ljMixed(outerCounter,innerCounter)%sigma6
125 ljMixed(innerCounter,outerCounter)%epsilon = ljMixed(outerCounter,innerCounter)%epsilon
126
127
128 tmpPtrInner => tmpPtrInner%next
129 innerCounter = innerCounter + 1
130 end do
131 ! advance pointers
132 tmpPtrOuter => tmpPtrOuter%next
133 if (associated(tmpPtrOuter)) then
134 tmpPtrInner => tmpPtrOuter%next
135 endif
136
137 end do
138
139 end subroutine createMixingList
140
141
142
143
144
145 !! Calculates the potential between two lj particles based on two lj_atype pointers, optionally returns second
146 !! derivatives.
147 subroutine getLjForce(r,pot,dudr,atype1,atype2,d2,status)
148 ! arguments
149 !! Length of vector between particles
150 real( kind = dp ), intent(in) :: r
151 !! Potential Energy
152 real( kind = dp ), intent(out) :: pot
153 !! Derivatve wrt postion
154 real( kind = dp ), intent(out) :: dudr
155 !! Second Derivative, optional, used mainly for normal mode calculations.
156 real( kind = dp ), intent(out), optional :: d2
157
158 type (lj_atype), pointer :: atype1
159 type (lj_atype), pointer :: atype2
160
161 integer, intent(out), optional :: status
162
163 ! local Variables
164 real( kind = dp ) :: sigma
165 real( kind = dp ) :: sigma2
166 real( kind = dp ) :: sigma6
167 real( kind = dp ) :: epsilon
168
169 real( kind = dp ) :: rcut
170 real( kind = dp ) :: rcut2
171 real( kind = dp ) :: rcut6
172 real( kind = dp ) :: r2
173 real( kind = dp ) :: r6
174
175 real( kind = dp ) :: t6
176 real( kind = dp ) :: t12
177 real( kind = dp ) :: tp6
178 real( kind = dp ) :: tp12
179 real( kind = dp ) :: delta
180
181 logical :: doSec = .false.
182
183 integer :: errorStat
184
185 !! Optional Argument Checking
186 ! Check to see if we need to do second derivatives
187
188 if (present(d2)) doSec = .true.
189 if (present(status)) status = 0
190
191 ! Look up the correct parameters in the mixing matrix
192 sigma = ljMixed(atype1%atype_ident,atype2%atype_ident)%sigma
193 sigma2 = ljMixed(atype1%atype_ident,atype2%atype_ident)%sigma2
194 sigma6 = ljMixed(atype1%atype_ident,atype2%atype_ident)%sigma6
195 epsilon = ljMixed(atype1%atype_ident,atype2%atype_ident)%epsilon
196
197
198
199
200 call getRcut(rcut,rcut2=rcut2,rcut6=rcut6,status=errorStat)
201
202 r2 = r * r
203 r6 = r2 * r2 * r2
204
205 t6 = sigma6/ r6
206 t12 = t6 * t6
207
208
209
210 tp6 = sigma6 / rcut6
211 tp12 = tp6*tp6
212
213 delta = -4.0E0_DP*epsilon * (tp12 - tp6)
214
215 if (r.le.rcut) then
216 pot = 4.0E0_DP * epsilon * (t12 - t6) + delta
217 dudr = 24.0E0_DP * epsilon * (t6 - 2.0E0_DP*t12) / r
218 if(doSec) d2 = 24.0E0_DP * epsilon * (26.0E0_DP*t12 - 7.0E0_DP*t6)/r/r
219 else
220 pot = 0.0E0_DP
221 dudr = 0.0E0_DP
222 if(doSec) d2 = 0.0E0_DP
223 endif
224
225 return
226
227
228
229 end subroutine getLJForce
230
231
232 !! Calculates the mixing for sigma or epslon based on character string for initialzition of mixing array.
233 function calcLJMix(thisParam,param1,param2,status) result(myMixParam)
234 character(len=*) :: thisParam
235 real(kind = dp) :: param1
236 real(kind = dp) :: param2
237 real(kind = dp ) :: myMixParam
238 character(len = getStringLen()) :: thisMixingRule
239 integer, optional :: status
240
241 !! get the mixing rules from the simulation
242 thisMixingRule = returnMixingRules()
243 myMixParam = 0.0_dp
244
245 if (present(status)) status = 0
246 select case (thisMixingRule)
247 case ("standard")
248 select case (thisParam)
249 case ("sigma")
250 myMixParam = 0.5_dp * (param1 + param2)
251 case ("epsilon")
252 myMixParam = sqrt(param1 * param2)
253 case default
254 status = -1
255 end select
256 case("LJglass")
257 case default
258 status = -1
259 end select
260 end function calcLJMix
261
262
263
264 end module lj_ff