ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE/libmdtools/calc_charge_charge.F90
Revision: 1144
Committed: Sat May 1 18:52:38 2004 UTC (20 years, 2 months ago) by tim
File size: 7789 byte(s)
Log Message:
C++ pass groupList to fortran

File Contents

# Content
1 module charge_charge
2
3 use force_globals
4 use definitions
5 use atype_module
6 use vector_class
7 use simulation
8 use status
9 #ifdef IS_MPI
10 use mpiSimulation
11 #endif
12 implicit none
13
14 PRIVATE
15 real(kind=dp), save :: ecr = 0.0_DP
16 real(kind=dp), save :: rt = 0.0_DP
17 real(kind=dp), save :: dielect = 0.0_DP
18 real(kind=dp), save :: pre = 0.0_DP
19
20 logical, save :: haveCutoffs = .false.
21 logical, save :: haveChargeMap = .false.
22 logical, save :: haveDielectric = .false.
23
24 public::setCutoffsCharge
25 public::do_charge_pair
26 public::initialize_charge
27
28 type :: ChargeList
29 real(kind=DP) :: charge = 0.0_DP
30 end type ChargeList
31
32 type(ChargeList), dimension(:), allocatable :: ChargeMap
33
34 contains
35
36 subroutine initialize_charge(this_dielect)
37 real(kind=dp), intent(in) :: this_dielect
38
39 dielect = this_dielect
40 haveDielectric = .true.
41
42 ! because setCutoffsCharge is called before initialize_charge
43 ! we need to call it agin to make sure all of the precalculation
44 ! value is correct. for the time being, just a quick hack
45 call setCutoffsCharge(ecr, rt)
46 return
47 end subroutine initialize_charge
48
49
50 subroutine setCutoffsCharge(this_ecr, this_rt)
51 real(kind=dp), intent(in) :: this_ecr, this_rt
52 ecr = this_ecr
53 rt = this_rt
54
55 ! pre converts from fundamental charge to kcal/mol
56 pre = 332.06508_DP
57
58 !if (.not.haveDielectric)then
59 ! write(default_error,*) 'Dielect constant in charge module is not set!'
60 !endif
61
62 haveCutoffs = .true.
63
64 return
65 end subroutine setCutoffsCharge
66
67 subroutine createChargeMap(status)
68 integer :: nAtypes
69 integer :: status
70 integer :: i
71 real (kind=DP) :: thisCharge
72 logical :: thisProperty
73
74 status = 0
75
76 nAtypes = getSize(atypes)
77
78 if (nAtypes == 0) then
79 status = -1
80 return
81 end if
82
83 if (.not. allocated(ChargeMap)) then
84 allocate(ChargeMap(nAtypes))
85 endif
86
87 do i = 1, nAtypes
88
89 call getElementProperty(atypes, i, "is_Charge", thisProperty)
90
91 if (thisProperty) then
92 call getElementProperty(atypes, i, "charge", thisCharge)
93 ChargeMap(i)%charge = thisCharge
94 endif
95
96 end do
97
98 haveChargeMap = .true.
99
100 end subroutine createChargeMap
101
102
103 subroutine do_charge_pair(atom1, atom2, d, rij, r2, dc, rcij, rc2, mfact, &
104 pot, f, do_pot, do_stress, molecular_cutoffs)
105
106 logical :: do_pot, do_stress, molecular_cutoffs
107
108 integer atom1, atom2, me1, me2, id1, id2
109 integer :: localError
110 real(kind=dp) :: rij, r2, q1, q2, rcij, rc2
111 real(kind=dp) :: drdx, drdy, drdz, dudr, fx, fy, fz
112 real(kind=dp) :: taper, dtdr, vterm
113
114 real( kind = dp ) :: pot
115 real( kind = dp ), dimension(3) :: d, dc
116 real( kind = dp ), dimension(3,nLocal) :: f
117 real( kind = dp ), dimension(nLocal) :: mfact
118 real( kind = dp ) :: theR, term1, term2
119 real( kind = dp ) :: fxab, fyab, fzab, fxba, fyba, fzba
120
121 if (.not. haveCutoffs) then
122 write(default_error,*) 'charge-charge does not have cutoffs set!'
123 return
124 endif
125
126 if (.not.haveChargeMap) then
127 localError = 0
128 call createChargeMap(localError)
129 if ( localError .ne. 0 ) then
130 call handleError("charge-charge", "ChargeMap creation failed!")
131 return
132 end if
133 endif
134
135 #ifdef IS_MPI
136 me1 = atid_Row(atom1)
137 me2 = atid_Col(atom2)
138 #else
139 me1 = atid(atom1)
140 me2 = atid(atom2)
141 #endif
142
143 q1 = ChargeMap(me1)%charge
144 q2 = ChargeMap(me2)%charge
145
146 if (molecular_cutoffs) then
147 theR = rcij
148 else
149 theR = rij
150 endif
151
152 if (theR.le.ecr) then
153
154 if (theR.lt.rt) then
155 taper = 1.0d0
156 dtdr = 0.0d0
157 else
158 taper = (ecr + 2.0d0*theR - 3.0d0*rt)*(ecr-theR)**2/ ((ecr-rt)**3)
159 dtdr = 6.0d0*(theR*theR - theR*rt - theR*ecr +ecr*rt)/((ecr-rt)**3)
160 endif
161
162 vterm = pre * q1 * q2 / rij
163
164 if (molecular_cutoffs) then
165
166 term1 = -vterm * (taper / rij)
167
168 fx = term1 * d(1) / rij
169 fy = term1 * d(2) / rij
170 fz = term1 * d(3) / rij
171
172 !term2 = vterm * dtdr * mfact(atom1)
173 term2 = vterm * dtdr
174
175 fxab = term2 * dc(1) / rcij
176 fyab = term2 * dc(2) / rcij
177 fzab = term2 * dc(3) / rcij
178
179 !term2 = vterm * dtdr * mfact(atom2)
180 term2 = vterm * dtdr
181
182 fxba = term2 * dc(1) / rcij
183 fyba = term2 * dc(2) / rcij
184 fzba = term2 * dc(3) / rcij
185
186 else
187
188 dudr = vterm * (dtdr - taper / rij)
189 drdx = d(1) / rij
190 drdy = d(2) / rij
191 drdz = d(3) / rij
192
193 fx = dudr * drdx
194 fy = dudr * drdy
195 fz = dudr * drdz
196
197 endif
198
199
200 #ifdef IS_MPI
201 if (do_pot) then
202 pot_Row(atom1) = pot_Row(atom1) + vterm*taper*0.5
203 pot_Col(atom2) = pot_Col(atom2) + vterm*taper*0.5
204 endif
205
206 f_Row(1,atom1) = f_Row(1,atom1) + fx
207 f_Row(2,atom1) = f_Row(2,atom1) + fy
208 f_Row(3,atom1) = f_Row(3,atom1) + fz
209
210 f_Col(1,atom2) = f_Col(1,atom2) - fx
211 f_Col(2,atom2) = f_Col(2,atom2) - fy
212 f_Col(3,atom2) = f_Col(3,atom2) - fz
213
214 if (molecular_cutoffs) then
215 f_Row(1,atom1) = f_Row(1,atom1) + fxab
216 f_Row(2,atom1) = f_Row(2,atom1) + fyab
217 f_Row(3,atom1) = f_Row(3,atom1) + fzab
218
219 f_Col(1,atom2) = f_Col(1,atom2) - fxba
220 f_Col(2,atom2) = f_Col(2,atom2) - fyba
221 f_Col(3,atom2) = f_Col(3,atom2) - fzba
222 endif
223
224 #else
225
226 if (do_pot) pot = pot + vterm*taper
227
228 f(1,atom1) = f(1,atom1) + fx
229 f(2,atom1) = f(2,atom1) + fy
230 f(3,atom1) = f(3,atom1) + fz
231
232 f(1,atom2) = f(1,atom2) - fx
233 f(2,atom2) = f(2,atom2) - fy
234 f(3,atom2) = f(3,atom2) - fz
235
236 if (molecular_cutoffs) then
237
238 f(1,atom1) = f(1,atom1) + fxab
239 f(2,atom1) = f(2,atom1) + fyab
240 f(3,atom1) = f(3,atom1) + fzab
241
242 f(1,atom2) = f(1,atom2) - fxba
243 f(2,atom2) = f(2,atom2) - fyba
244 f(3,atom2) = f(3,atom2) - fzba
245 endif
246
247 #endif
248
249 if (do_stress) then
250
251 #ifdef IS_MPI
252 id1 = tagRow(atom1)
253 id2 = tagColumn(atom2)
254 #else
255 id1 = atom1
256 id2 = atom2
257 #endif
258
259
260 if (molMembershipList(id1) .ne. molMembershipList(id2)) then
261
262 ! because the d vector is the rj - ri vector, and
263 ! because fx, fy, fz are the force on atom i, we need a
264 ! negative sign here:
265
266 tau_Temp(1) = tau_Temp(1) - d(1) * fx
267 tau_Temp(2) = tau_Temp(2) - d(1) * fy
268 tau_Temp(3) = tau_Temp(3) - d(1) * fz
269 tau_Temp(4) = tau_Temp(4) - d(2) * fx
270 tau_Temp(5) = tau_Temp(5) - d(2) * fy
271 tau_Temp(6) = tau_Temp(6) - d(2) * fz
272 tau_Temp(8) = tau_Temp(8) - d(3) * fy
273 tau_Temp(9) = tau_Temp(9) - d(3) * fz
274
275 if (molecular_cutoffs) then
276
277 tau_Temp(1) = tau_Temp(1) - d(1) * fxab
278 tau_Temp(2) = tau_Temp(2) - d(1) * fyab
279 tau_Temp(3) = tau_Temp(3) - d(1) * fzab
280 tau_Temp(4) = tau_Temp(4) - d(2) * fxab
281 tau_Temp(5) = tau_Temp(5) - d(2) * fyab
282 tau_Temp(6) = tau_Temp(6) - d(2) * fzab
283 tau_Temp(8) = tau_Temp(8) - d(3) * fyab
284 tau_Temp(9) = tau_Temp(9) - d(3) * fzab
285 endif
286
287 virial_Temp = virial_Temp + &
288 (tau_Temp(1) + tau_Temp(5) + tau_Temp(9))
289
290 endif
291 endif
292
293 endif
294 return
295 end subroutine do_charge_pair
296
297 end module charge_charge