ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE-2.0/src/UseTheForce/DarkSide/electrostatic.F90
Revision: 2552
Committed: Thu Jan 12 16:47:25 2006 UTC (18 years, 6 months ago) by chrisfen
File size: 52567 byte(s)
Log Message:
unifying function name in electrostatics

File Contents

# User Rev Content
1 gezelter 2095 !!
2     !! Copyright (c) 2005 The University of Notre Dame. All Rights Reserved.
3     !!
4     !! The University of Notre Dame grants you ("Licensee") a
5     !! non-exclusive, royalty free, license to use, modify and
6     !! redistribute this software in source and binary code form, provided
7     !! that the following conditions are met:
8     !!
9     !! 1. Acknowledgement of the program authors must be made in any
10     !! publication of scientific results based in part on use of the
11     !! program. An acceptable form of acknowledgement is citation of
12     !! the article in which the program was described (Matthew
13     !! A. Meineke, Charles F. Vardeman II, Teng Lin, Christopher
14     !! J. Fennell and J. Daniel Gezelter, "OOPSE: An Object-Oriented
15     !! Parallel Simulation Engine for Molecular Dynamics,"
16     !! J. Comput. Chem. 26, pp. 252-271 (2005))
17     !!
18     !! 2. Redistributions of source code must retain the above copyright
19     !! notice, this list of conditions and the following disclaimer.
20     !!
21     !! 3. Redistributions in binary form must reproduce the above copyright
22     !! notice, this list of conditions and the following disclaimer in the
23     !! documentation and/or other materials provided with the
24     !! distribution.
25     !!
26     !! This software is provided "AS IS," without a warranty of any
27     !! kind. All express or implied conditions, representations and
28     !! warranties, including any implied warranty of merchantability,
29     !! fitness for a particular purpose or non-infringement, are hereby
30     !! excluded. The University of Notre Dame and its licensors shall not
31     !! be liable for any damages suffered by licensee as a result of
32     !! using, modifying or distributing the software or its
33     !! derivatives. In no event will the University of Notre Dame or its
34     !! licensors be liable for any lost revenue, profit or data, or for
35     !! direct, indirect, special, consequential, incidental or punitive
36     !! damages, however caused and regardless of the theory of liability,
37     !! arising out of the use of or inability to use software, even if the
38     !! University of Notre Dame has been advised of the possibility of
39     !! such damages.
40     !!
41    
42     module electrostatic_module
43 gezelter 2204
44 gezelter 2095 use force_globals
45     use definitions
46     use atype_module
47     use vector_class
48     use simulation
49     use status
50     #ifdef IS_MPI
51     use mpiSimulation
52     #endif
53     implicit none
54    
55     PRIVATE
56    
57 chuckv 2355
58 gezelter 2301 #define __FORTRAN90
59 chuckv 2355 #include "UseTheForce/DarkSide/fInteractionMap.h"
60 gezelter 2301 #include "UseTheForce/DarkSide/fElectrostaticSummationMethod.h"
61 chrisfen 2415 #include "UseTheForce/DarkSide/fElectrostaticScreeningMethod.h"
62 gezelter 2301
63 chuckv 2355
64 gezelter 2118 !! these prefactors convert the multipole interactions into kcal / mol
65     !! all were computed assuming distances are measured in angstroms
66     !! Charge-Charge, assuming charges are measured in electrons
67 gezelter 2095 real(kind=dp), parameter :: pre11 = 332.0637778_dp
68 gezelter 2118 !! Charge-Dipole, assuming charges are measured in electrons, and
69     !! dipoles are measured in debyes
70     real(kind=dp), parameter :: pre12 = 69.13373_dp
71     !! Dipole-Dipole, assuming dipoles are measured in debyes
72     real(kind=dp), parameter :: pre22 = 14.39325_dp
73     !! Charge-Quadrupole, assuming charges are measured in electrons, and
74     !! quadrupoles are measured in 10^-26 esu cm^2
75     !! This unit is also known affectionately as an esu centi-barn.
76     real(kind=dp), parameter :: pre14 = 69.13373_dp
77 gezelter 2095
78 chrisfen 2411 !! variables to handle different summation methods for long-range
79     !! electrostatics:
80 gezelter 2301 integer, save :: summationMethod = NONE
81 chrisfen 2409 integer, save :: screeningMethod = UNDAMPED
82 chrisfen 2302 logical, save :: summationMethodChecked = .false.
83 gezelter 2301 real(kind=DP), save :: defaultCutoff = 0.0_DP
84 chrisfen 2381 real(kind=DP), save :: defaultCutoff2 = 0.0_DP
85 gezelter 2301 logical, save :: haveDefaultCutoff = .false.
86     real(kind=DP), save :: dampingAlpha = 0.0_DP
87 chrisfen 2415 real(kind=DP), save :: alpha2 = 0.0_DP
88 gezelter 2301 logical, save :: haveDampingAlpha = .false.
89 chrisfen 2381 real(kind=DP), save :: dielectric = 1.0_DP
90 gezelter 2301 logical, save :: haveDielectric = .false.
91     real(kind=DP), save :: constEXP = 0.0_DP
92 chrisfen 2381 real(kind=dp), save :: rcuti = 0.0_DP
93     real(kind=dp), save :: rcuti2 = 0.0_DP
94     real(kind=dp), save :: rcuti3 = 0.0_DP
95     real(kind=dp), save :: rcuti4 = 0.0_DP
96     real(kind=dp), save :: alphaPi = 0.0_DP
97     real(kind=dp), save :: invRootPi = 0.0_DP
98     real(kind=dp), save :: rrf = 1.0_DP
99     real(kind=dp), save :: rt = 1.0_DP
100     real(kind=dp), save :: rrfsq = 1.0_DP
101     real(kind=dp), save :: preRF = 0.0_DP
102 chrisfen 2394 real(kind=dp), save :: preRF2 = 0.0_DP
103 chrisfen 2415 real(kind=dp), save :: f0 = 1.0_DP
104     real(kind=dp), save :: f1 = 1.0_DP
105     real(kind=dp), save :: f2 = 0.0_DP
106 chrisfen 2548 real(kind=dp), save :: f3 = 0.0_DP
107     real(kind=dp), save :: f4 = 0.0_DP
108 chrisfen 2415 real(kind=dp), save :: f0c = 1.0_DP
109     real(kind=dp), save :: f1c = 1.0_DP
110     real(kind=dp), save :: f2c = 0.0_DP
111 chrisfen 2548 real(kind=dp), save :: f3c = 0.0_DP
112     real(kind=dp), save :: f4c = 0.0_DP
113 chrisfen 2415
114 gezelter 2508 #if defined(__IFC) || defined(__PGI)
115 chuckv 2331 ! error function for ifc version > 7.
116 chuckv 2330 double precision, external :: derfc
117 chuckv 2331 #endif
118    
119 chrisfen 2552 public :: setElectrostaticSummationMethod
120 chrisfen 2409 public :: setScreeningMethod
121 gezelter 2301 public :: setElectrostaticCutoffRadius
122 chrisfen 2409 public :: setDampingAlpha
123 gezelter 2301 public :: setReactionFieldDielectric
124 gezelter 2095 public :: newElectrostaticType
125     public :: setCharge
126     public :: setDipoleMoment
127     public :: setSplitDipoleDistance
128     public :: setQuadrupoleMoments
129     public :: doElectrostaticPair
130     public :: getCharge
131     public :: getDipoleMoment
132 chuckv 2189 public :: destroyElectrostaticTypes
133 chrisfen 2402 public :: self_self
134 chrisfen 2399 public :: rf_self_excludes
135 gezelter 2095
136     type :: Electrostatic
137     integer :: c_ident
138     logical :: is_Charge = .false.
139     logical :: is_Dipole = .false.
140     logical :: is_SplitDipole = .false.
141     logical :: is_Quadrupole = .false.
142 chrisfen 2229 logical :: is_Tap = .false.
143 gezelter 2095 real(kind=DP) :: charge = 0.0_DP
144     real(kind=DP) :: dipole_moment = 0.0_DP
145     real(kind=DP) :: split_dipole_distance = 0.0_DP
146     real(kind=DP), dimension(3) :: quadrupole_moments = 0.0_DP
147     end type Electrostatic
148    
149     type(Electrostatic), dimension(:), allocatable :: ElectrostaticMap
150    
151     contains
152    
153 chrisfen 2552 subroutine setElectrostaticSummationMethod(the_ESM)
154 gezelter 2301 integer, intent(in) :: the_ESM
155    
156     if ((the_ESM .le. 0) .or. (the_ESM .gt. REACTION_FIELD)) then
157 chrisfen 2552 call handleError("setElectrostaticSummationMethod", "Unsupported Summation Method")
158 gezelter 2301 endif
159    
160 chrisfen 2309 summationMethod = the_ESM
161 chrisfen 2325
162 chrisfen 2552 end subroutine setElectrostaticSummationMethod
163 gezelter 2301
164 chrisfen 2409 subroutine setScreeningMethod(the_SM)
165     integer, intent(in) :: the_SM
166     screeningMethod = the_SM
167     end subroutine setScreeningMethod
168    
169 chrisfen 2381 subroutine setElectrostaticCutoffRadius(thisRcut, thisRsw)
170 gezelter 2301 real(kind=dp), intent(in) :: thisRcut
171 chrisfen 2381 real(kind=dp), intent(in) :: thisRsw
172 gezelter 2301 defaultCutoff = thisRcut
173 chrisfen 2548 defaultCutoff2 = defaultCutoff*defaultCutoff
174 chrisfen 2381 rrf = defaultCutoff
175     rt = thisRsw
176 gezelter 2301 haveDefaultCutoff = .true.
177     end subroutine setElectrostaticCutoffRadius
178    
179 chrisfen 2409 subroutine setDampingAlpha(thisAlpha)
180 gezelter 2301 real(kind=dp), intent(in) :: thisAlpha
181     dampingAlpha = thisAlpha
182 chrisfen 2415 alpha2 = dampingAlpha*dampingAlpha
183 gezelter 2301 haveDampingAlpha = .true.
184 chrisfen 2409 end subroutine setDampingAlpha
185 gezelter 2301
186     subroutine setReactionFieldDielectric(thisDielectric)
187     real(kind=dp), intent(in) :: thisDielectric
188     dielectric = thisDielectric
189     haveDielectric = .true.
190     end subroutine setReactionFieldDielectric
191    
192 gezelter 2095 subroutine newElectrostaticType(c_ident, is_Charge, is_Dipole, &
193 chrisfen 2229 is_SplitDipole, is_Quadrupole, is_Tap, status)
194 gezelter 2204
195 gezelter 2095 integer, intent(in) :: c_ident
196     logical, intent(in) :: is_Charge
197     logical, intent(in) :: is_Dipole
198     logical, intent(in) :: is_SplitDipole
199     logical, intent(in) :: is_Quadrupole
200 chrisfen 2229 logical, intent(in) :: is_Tap
201 gezelter 2095 integer, intent(out) :: status
202     integer :: nAtypes, myATID, i, j
203    
204     status = 0
205     myATID = getFirstMatchingElement(atypes, "c_ident", c_ident)
206 gezelter 2204
207 gezelter 2095 !! Be simple-minded and assume that we need an ElectrostaticMap that
208     !! is the same size as the total number of atom types
209    
210     if (.not.allocated(ElectrostaticMap)) then
211 gezelter 2204
212 gezelter 2095 nAtypes = getSize(atypes)
213 gezelter 2204
214 gezelter 2095 if (nAtypes == 0) then
215     status = -1
216     return
217     end if
218 gezelter 2204
219 gezelter 2095 if (.not. allocated(ElectrostaticMap)) then
220     allocate(ElectrostaticMap(nAtypes))
221     endif
222 gezelter 2204
223 gezelter 2095 end if
224    
225     if (myATID .gt. size(ElectrostaticMap)) then
226     status = -1
227     return
228     endif
229 gezelter 2204
230 gezelter 2095 ! set the values for ElectrostaticMap for this atom type:
231    
232     ElectrostaticMap(myATID)%c_ident = c_ident
233     ElectrostaticMap(myATID)%is_Charge = is_Charge
234     ElectrostaticMap(myATID)%is_Dipole = is_Dipole
235     ElectrostaticMap(myATID)%is_SplitDipole = is_SplitDipole
236     ElectrostaticMap(myATID)%is_Quadrupole = is_Quadrupole
237 chrisfen 2229 ElectrostaticMap(myATID)%is_Tap = is_Tap
238 gezelter 2204
239 gezelter 2095 end subroutine newElectrostaticType
240    
241     subroutine setCharge(c_ident, charge, status)
242     integer, intent(in) :: c_ident
243     real(kind=dp), intent(in) :: charge
244     integer, intent(out) :: status
245     integer :: myATID
246    
247     status = 0
248     myATID = getFirstMatchingElement(atypes, "c_ident", c_ident)
249    
250     if (.not.allocated(ElectrostaticMap)) then
251     call handleError("electrostatic", "no ElectrostaticMap was present before first call of setCharge!")
252     status = -1
253     return
254     end if
255    
256     if (myATID .gt. size(ElectrostaticMap)) then
257     call handleError("electrostatic", "ElectrostaticMap was found to be too small during setCharge!")
258     status = -1
259     return
260     endif
261    
262     if (.not.ElectrostaticMap(myATID)%is_Charge) then
263     call handleError("electrostatic", "Attempt to setCharge of an atom type that is not a charge!")
264     status = -1
265     return
266 gezelter 2204 endif
267 gezelter 2095
268     ElectrostaticMap(myATID)%charge = charge
269     end subroutine setCharge
270    
271     subroutine setDipoleMoment(c_ident, dipole_moment, status)
272     integer, intent(in) :: c_ident
273     real(kind=dp), intent(in) :: dipole_moment
274     integer, intent(out) :: status
275     integer :: myATID
276    
277     status = 0
278     myATID = getFirstMatchingElement(atypes, "c_ident", c_ident)
279    
280     if (.not.allocated(ElectrostaticMap)) then
281     call handleError("electrostatic", "no ElectrostaticMap was present before first call of setDipoleMoment!")
282     status = -1
283     return
284     end if
285    
286     if (myATID .gt. size(ElectrostaticMap)) then
287     call handleError("electrostatic", "ElectrostaticMap was found to be too small during setDipoleMoment!")
288     status = -1
289     return
290     endif
291    
292     if (.not.ElectrostaticMap(myATID)%is_Dipole) then
293     call handleError("electrostatic", "Attempt to setDipoleMoment of an atom type that is not a dipole!")
294     status = -1
295     return
296     endif
297    
298     ElectrostaticMap(myATID)%dipole_moment = dipole_moment
299     end subroutine setDipoleMoment
300    
301     subroutine setSplitDipoleDistance(c_ident, split_dipole_distance, status)
302     integer, intent(in) :: c_ident
303     real(kind=dp), intent(in) :: split_dipole_distance
304     integer, intent(out) :: status
305     integer :: myATID
306    
307     status = 0
308     myATID = getFirstMatchingElement(atypes, "c_ident", c_ident)
309    
310     if (.not.allocated(ElectrostaticMap)) then
311     call handleError("electrostatic", "no ElectrostaticMap was present before first call of setSplitDipoleDistance!")
312     status = -1
313     return
314     end if
315    
316     if (myATID .gt. size(ElectrostaticMap)) then
317     call handleError("electrostatic", "ElectrostaticMap was found to be too small during setSplitDipoleDistance!")
318     status = -1
319     return
320     endif
321    
322     if (.not.ElectrostaticMap(myATID)%is_SplitDipole) then
323     call handleError("electrostatic", "Attempt to setSplitDipoleDistance of an atom type that is not a splitDipole!")
324     status = -1
325     return
326     endif
327    
328     ElectrostaticMap(myATID)%split_dipole_distance = split_dipole_distance
329     end subroutine setSplitDipoleDistance
330    
331     subroutine setQuadrupoleMoments(c_ident, quadrupole_moments, status)
332     integer, intent(in) :: c_ident
333     real(kind=dp), intent(in), dimension(3) :: quadrupole_moments
334     integer, intent(out) :: status
335     integer :: myATID, i, j
336    
337     status = 0
338     myATID = getFirstMatchingElement(atypes, "c_ident", c_ident)
339    
340     if (.not.allocated(ElectrostaticMap)) then
341     call handleError("electrostatic", "no ElectrostaticMap was present before first call of setQuadrupoleMoments!")
342     status = -1
343     return
344     end if
345    
346     if (myATID .gt. size(ElectrostaticMap)) then
347     call handleError("electrostatic", "ElectrostaticMap was found to be too small during setQuadrupoleMoments!")
348     status = -1
349     return
350     endif
351    
352     if (.not.ElectrostaticMap(myATID)%is_Quadrupole) then
353     call handleError("electrostatic", "Attempt to setQuadrupoleMoments of an atom type that is not a quadrupole!")
354     status = -1
355     return
356     endif
357 gezelter 2204
358 gezelter 2095 do i = 1, 3
359 gezelter 2204 ElectrostaticMap(myATID)%quadrupole_moments(i) = &
360     quadrupole_moments(i)
361     enddo
362 gezelter 2095
363     end subroutine setQuadrupoleMoments
364    
365 gezelter 2204
366 gezelter 2095 function getCharge(atid) result (c)
367     integer, intent(in) :: atid
368     integer :: localError
369     real(kind=dp) :: c
370 gezelter 2204
371 gezelter 2095 if (.not.allocated(ElectrostaticMap)) then
372     call handleError("electrostatic", "no ElectrostaticMap was present before first call of getCharge!")
373     return
374     end if
375 gezelter 2204
376 gezelter 2095 if (.not.ElectrostaticMap(atid)%is_Charge) then
377     call handleError("electrostatic", "getCharge was called for an atom type that isn't a charge!")
378     return
379     endif
380 gezelter 2204
381 gezelter 2095 c = ElectrostaticMap(atid)%charge
382     end function getCharge
383    
384     function getDipoleMoment(atid) result (dm)
385     integer, intent(in) :: atid
386     integer :: localError
387     real(kind=dp) :: dm
388 gezelter 2204
389 gezelter 2095 if (.not.allocated(ElectrostaticMap)) then
390     call handleError("electrostatic", "no ElectrostaticMap was present before first call of getDipoleMoment!")
391     return
392     end if
393 gezelter 2204
394 gezelter 2095 if (.not.ElectrostaticMap(atid)%is_Dipole) then
395     call handleError("electrostatic", "getDipoleMoment was called for an atom type that isn't a dipole!")
396     return
397     endif
398 gezelter 2204
399 gezelter 2095 dm = ElectrostaticMap(atid)%dipole_moment
400     end function getDipoleMoment
401    
402 gezelter 2301 subroutine checkSummationMethod()
403    
404 chrisfen 2306 if (.not.haveDefaultCutoff) then
405     call handleError("checkSummationMethod", "no Default Cutoff set!")
406     endif
407    
408     rcuti = 1.0d0 / defaultCutoff
409     rcuti2 = rcuti*rcuti
410     rcuti3 = rcuti2*rcuti
411     rcuti4 = rcuti2*rcuti2
412    
413 chrisfen 2409 if (screeningMethod .eq. DAMPED) then
414 chrisfen 2402 if (.not.haveDampingAlpha) then
415     call handleError("checkSummationMethod", "no Damping Alpha set!")
416     endif
417    
418     if (.not.haveDefaultCutoff) then
419     call handleError("checkSummationMethod", "no Default Cutoff set!")
420     endif
421 chrisfen 2302
422 chrisfen 2548 constEXP = exp(-alpha2*defaultCutoff2)
423 chrisfen 2402 invRootPi = 0.56418958354775628695d0
424 chrisfen 2415 alphaPi = 2.0d0*dampingAlpha*invRootPi
425     f0c = derfc(dampingAlpha*defaultCutoff)
426     f1c = alphaPi*defaultCutoff*constEXP + f0c
427 chrisfen 2548 f2c = alphaPi*2.0d0*alpha2*constEXP
428     f3c = alphaPi*2.0d0*alpha2*constEXP*defaultCutoff2*defaultCutoff
429 gezelter 2301 endif
430    
431 chrisfen 2302 if (summationMethod .eq. REACTION_FIELD) then
432 chrisfen 2402 if (haveDielectric) then
433     defaultCutoff2 = defaultCutoff*defaultCutoff
434     preRF = (dielectric-1.0d0) / &
435     ((2.0d0*dielectric+1.0d0)*defaultCutoff2*defaultCutoff)
436     preRF2 = 2.0d0*preRF
437     else
438     call handleError("checkSummationMethod", "Dielectric not set")
439 chrisfen 2302 endif
440 chrisfen 2402
441 chrisfen 2302 endif
442    
443     summationMethodChecked = .true.
444 gezelter 2301 end subroutine checkSummationMethod
445    
446 chrisfen 2411
447 gezelter 2461 subroutine doElectrostaticPair(atom1, atom2, d, rij, r2, rcut, sw, &
448 chrisfen 2411 vpair, fpair, pot, eFrame, f, t, do_pot)
449 gezelter 2204
450 chrisfen 2402 logical, intent(in) :: do_pot
451 gezelter 2204
452 gezelter 2095 integer, intent(in) :: atom1, atom2
453     integer :: localError
454    
455 gezelter 2461 real(kind=dp), intent(in) :: rij, r2, sw, rcut
456 gezelter 2095 real(kind=dp), intent(in), dimension(3) :: d
457     real(kind=dp), intent(inout) :: vpair
458 chrisfen 2402 real(kind=dp), intent(inout), dimension(3) :: fpair
459 gezelter 2095
460 chrisfen 2325 real( kind = dp ) :: pot
461 gezelter 2095 real( kind = dp ), dimension(9,nLocal) :: eFrame
462     real( kind = dp ), dimension(3,nLocal) :: f
463 chrisfen 2409 real( kind = dp ), dimension(3,nLocal) :: felec
464 gezelter 2095 real( kind = dp ), dimension(3,nLocal) :: t
465 gezelter 2204
466 gezelter 2123 real (kind = dp), dimension(3) :: ux_i, uy_i, uz_i
467     real (kind = dp), dimension(3) :: ux_j, uy_j, uz_j
468     real (kind = dp), dimension(3) :: dudux_i, duduy_i, duduz_i
469     real (kind = dp), dimension(3) :: dudux_j, duduy_j, duduz_j
470 gezelter 2095
471     logical :: i_is_Charge, i_is_Dipole, i_is_SplitDipole, i_is_Quadrupole
472     logical :: j_is_Charge, j_is_Dipole, j_is_SplitDipole, j_is_Quadrupole
473 chrisfen 2229 logical :: i_is_Tap, j_is_Tap
474 gezelter 2095 integer :: me1, me2, id1, id2
475     real (kind=dp) :: q_i, q_j, mu_i, mu_j, d_i, d_j
476 gezelter 2123 real (kind=dp) :: qxx_i, qyy_i, qzz_i
477     real (kind=dp) :: qxx_j, qyy_j, qzz_j
478     real (kind=dp) :: cx_i, cy_i, cz_i
479     real (kind=dp) :: cx_j, cy_j, cz_j
480     real (kind=dp) :: cx2, cy2, cz2
481 chrisfen 2418 real (kind=dp) :: ct_i, ct_j, ct_ij, a0, a1
482 gezelter 2105 real (kind=dp) :: riji, ri, ri2, ri3, ri4
483 chrisfen 2296 real (kind=dp) :: pref, vterm, epot, dudr, vterm1, vterm2
484 gezelter 2105 real (kind=dp) :: xhat, yhat, zhat
485 gezelter 2095 real (kind=dp) :: dudx, dudy, dudz
486 chrisfen 2325 real (kind=dp) :: scale, sc2, bigR
487 chrisfen 2415 real (kind=dp) :: varEXP
488 chrisfen 2418 real (kind=dp) :: pot_term
489 chrisfen 2394 real (kind=dp) :: preVal, rfVal
490 chrisfen 2548 real (kind=dp) :: f13, f134
491 gezelter 2095
492     if (.not.allocated(ElectrostaticMap)) then
493     call handleError("electrostatic", "no ElectrostaticMap was present before first call of do_electrostatic_pair!")
494     return
495     end if
496    
497 gezelter 2301 if (.not.summationMethodChecked) then
498     call checkSummationMethod()
499     endif
500    
501 gezelter 2095 #ifdef IS_MPI
502     me1 = atid_Row(atom1)
503     me2 = atid_Col(atom2)
504     #else
505     me1 = atid(atom1)
506     me2 = atid(atom2)
507     #endif
508    
509     !! some variables we'll need independent of electrostatic type:
510    
511     riji = 1.0d0 / rij
512 chrisfen 2343
513 gezelter 2105 xhat = d(1) * riji
514     yhat = d(2) * riji
515     zhat = d(3) * riji
516 gezelter 2095
517     !! logicals
518     i_is_Charge = ElectrostaticMap(me1)%is_Charge
519     i_is_Dipole = ElectrostaticMap(me1)%is_Dipole
520     i_is_SplitDipole = ElectrostaticMap(me1)%is_SplitDipole
521     i_is_Quadrupole = ElectrostaticMap(me1)%is_Quadrupole
522 chrisfen 2229 i_is_Tap = ElectrostaticMap(me1)%is_Tap
523 gezelter 2095
524     j_is_Charge = ElectrostaticMap(me2)%is_Charge
525     j_is_Dipole = ElectrostaticMap(me2)%is_Dipole
526     j_is_SplitDipole = ElectrostaticMap(me2)%is_SplitDipole
527     j_is_Quadrupole = ElectrostaticMap(me2)%is_Quadrupole
528 chrisfen 2229 j_is_Tap = ElectrostaticMap(me2)%is_Tap
529 gezelter 2095
530     if (i_is_Charge) then
531     q_i = ElectrostaticMap(me1)%charge
532     endif
533 gezelter 2204
534 gezelter 2095 if (i_is_Dipole) then
535     mu_i = ElectrostaticMap(me1)%dipole_moment
536     #ifdef IS_MPI
537 gezelter 2123 uz_i(1) = eFrame_Row(3,atom1)
538     uz_i(2) = eFrame_Row(6,atom1)
539     uz_i(3) = eFrame_Row(9,atom1)
540 gezelter 2095 #else
541 gezelter 2123 uz_i(1) = eFrame(3,atom1)
542     uz_i(2) = eFrame(6,atom1)
543     uz_i(3) = eFrame(9,atom1)
544 gezelter 2095 #endif
545 gezelter 2123 ct_i = uz_i(1)*xhat + uz_i(2)*yhat + uz_i(3)*zhat
546 gezelter 2095
547     if (i_is_SplitDipole) then
548     d_i = ElectrostaticMap(me1)%split_dipole_distance
549     endif
550 gezelter 2204
551 gezelter 2095 endif
552    
553 gezelter 2123 if (i_is_Quadrupole) then
554     qxx_i = ElectrostaticMap(me1)%quadrupole_moments(1)
555     qyy_i = ElectrostaticMap(me1)%quadrupole_moments(2)
556     qzz_i = ElectrostaticMap(me1)%quadrupole_moments(3)
557     #ifdef IS_MPI
558     ux_i(1) = eFrame_Row(1,atom1)
559     ux_i(2) = eFrame_Row(4,atom1)
560     ux_i(3) = eFrame_Row(7,atom1)
561     uy_i(1) = eFrame_Row(2,atom1)
562     uy_i(2) = eFrame_Row(5,atom1)
563     uy_i(3) = eFrame_Row(8,atom1)
564     uz_i(1) = eFrame_Row(3,atom1)
565     uz_i(2) = eFrame_Row(6,atom1)
566     uz_i(3) = eFrame_Row(9,atom1)
567     #else
568     ux_i(1) = eFrame(1,atom1)
569     ux_i(2) = eFrame(4,atom1)
570     ux_i(3) = eFrame(7,atom1)
571     uy_i(1) = eFrame(2,atom1)
572     uy_i(2) = eFrame(5,atom1)
573     uy_i(3) = eFrame(8,atom1)
574     uz_i(1) = eFrame(3,atom1)
575     uz_i(2) = eFrame(6,atom1)
576     uz_i(3) = eFrame(9,atom1)
577     #endif
578     cx_i = ux_i(1)*xhat + ux_i(2)*yhat + ux_i(3)*zhat
579     cy_i = uy_i(1)*xhat + uy_i(2)*yhat + uy_i(3)*zhat
580     cz_i = uz_i(1)*xhat + uz_i(2)*yhat + uz_i(3)*zhat
581     endif
582    
583 gezelter 2095 if (j_is_Charge) then
584     q_j = ElectrostaticMap(me2)%charge
585     endif
586 gezelter 2204
587 gezelter 2095 if (j_is_Dipole) then
588     mu_j = ElectrostaticMap(me2)%dipole_moment
589     #ifdef IS_MPI
590 gezelter 2123 uz_j(1) = eFrame_Col(3,atom2)
591     uz_j(2) = eFrame_Col(6,atom2)
592     uz_j(3) = eFrame_Col(9,atom2)
593 gezelter 2095 #else
594 gezelter 2123 uz_j(1) = eFrame(3,atom2)
595     uz_j(2) = eFrame(6,atom2)
596     uz_j(3) = eFrame(9,atom2)
597 gezelter 2095 #endif
598 chrisfen 2162 ct_j = uz_j(1)*xhat + uz_j(2)*yhat + uz_j(3)*zhat
599 gezelter 2095
600     if (j_is_SplitDipole) then
601     d_j = ElectrostaticMap(me2)%split_dipole_distance
602     endif
603     endif
604    
605 gezelter 2123 if (j_is_Quadrupole) then
606     qxx_j = ElectrostaticMap(me2)%quadrupole_moments(1)
607     qyy_j = ElectrostaticMap(me2)%quadrupole_moments(2)
608     qzz_j = ElectrostaticMap(me2)%quadrupole_moments(3)
609     #ifdef IS_MPI
610     ux_j(1) = eFrame_Col(1,atom2)
611     ux_j(2) = eFrame_Col(4,atom2)
612     ux_j(3) = eFrame_Col(7,atom2)
613     uy_j(1) = eFrame_Col(2,atom2)
614     uy_j(2) = eFrame_Col(5,atom2)
615     uy_j(3) = eFrame_Col(8,atom2)
616     uz_j(1) = eFrame_Col(3,atom2)
617     uz_j(2) = eFrame_Col(6,atom2)
618     uz_j(3) = eFrame_Col(9,atom2)
619     #else
620     ux_j(1) = eFrame(1,atom2)
621     ux_j(2) = eFrame(4,atom2)
622     ux_j(3) = eFrame(7,atom2)
623     uy_j(1) = eFrame(2,atom2)
624     uy_j(2) = eFrame(5,atom2)
625     uy_j(3) = eFrame(8,atom2)
626     uz_j(1) = eFrame(3,atom2)
627     uz_j(2) = eFrame(6,atom2)
628     uz_j(3) = eFrame(9,atom2)
629     #endif
630     cx_j = ux_j(1)*xhat + ux_j(2)*yhat + ux_j(3)*zhat
631     cy_j = uy_j(1)*xhat + uy_j(2)*yhat + uy_j(3)*zhat
632     cz_j = uz_j(1)*xhat + uz_j(2)*yhat + uz_j(3)*zhat
633     endif
634 chrisfen 2251
635 gezelter 2095 epot = 0.0_dp
636     dudx = 0.0_dp
637     dudy = 0.0_dp
638     dudz = 0.0_dp
639    
640 gezelter 2123 dudux_i = 0.0_dp
641     duduy_i = 0.0_dp
642     duduz_i = 0.0_dp
643 gezelter 2095
644 gezelter 2123 dudux_j = 0.0_dp
645     duduy_j = 0.0_dp
646     duduz_j = 0.0_dp
647 gezelter 2095
648     if (i_is_Charge) then
649    
650     if (j_is_Charge) then
651 chrisfen 2438 if (screeningMethod .eq. DAMPED) then
652     f0 = derfc(dampingAlpha*rij)
653     varEXP = exp(-alpha2*rij*rij)
654     f1 = alphaPi*rij*varEXP + f0
655     endif
656 gezelter 2204
657 chrisfen 2438 preVal = pre11 * q_i * q_j
658    
659 chrisfen 2409 if (summationMethod .eq. SHIFTED_POTENTIAL) then
660 chrisfen 2438 vterm = preVal * (riji*f0 - rcuti*f0c)
661 chrisfen 2296
662 chrisfen 2438 dudr = -sw * preVal * riji * riji * f1
663    
664 chrisfen 2409 elseif (summationMethod .eq. SHIFTED_FORCE) then
665 chrisfen 2438 vterm = preVal * ( riji*f0 - rcuti*f0c + &
666 chrisfen 2415 f1c*rcuti2*(rij-defaultCutoff) )
667    
668 chrisfen 2438 dudr = -sw*preVal * (riji*riji*f1 - rcuti2*f1c)
669    
670 chrisfen 2394 elseif (summationMethod .eq. REACTION_FIELD) then
671     rfVal = preRF*rij*rij
672     vterm = preVal * ( riji + rfVal )
673 chrisfen 2399
674 chrisfen 2394 dudr = sw * preVal * ( 2.0d0*rfVal - riji )*riji
675 chrisfen 2438
676 chrisfen 2296 else
677 chrisfen 2438 vterm = preVal * riji*f0
678 chrisfen 2296
679 chrisfen 2438 dudr = - sw * preVal * riji*riji*f1
680    
681 chrisfen 2296 endif
682    
683 chrisfen 2438 vpair = vpair + vterm
684     epot = epot + sw*vterm
685    
686     dudx = dudx + dudr * xhat
687     dudy = dudy + dudr * yhat
688     dudz = dudz + dudr * zhat
689    
690 gezelter 2095 endif
691    
692     if (j_is_Dipole) then
693 chrisfen 2548 if (screeningMethod .eq. DAMPED) then
694     f0 = derfc(dampingAlpha*rij)
695     varEXP = exp(-alpha2*rij*rij)
696     f1 = alphaPi*rij*varEXP + f0
697     f3 = alphaPi*2.0d0*alpha2*varEXP*rij*rij*rij
698     endif
699 gezelter 2095
700 chrisfen 2325 pref = pre12 * q_i * mu_j
701 gezelter 2095
702 chrisfen 2409 if (summationMethod .eq. REACTION_FIELD) then
703 chrisfen 2399 ri2 = riji * riji
704     ri3 = ri2 * riji
705 chrisfen 2395
706     vterm = - pref * ct_j * ( ri2 - preRF2*rij )
707     vpair = vpair + vterm
708     epot = epot + sw*vterm
709    
710     !! this has a + sign in the () because the rij vector is
711     !! r_j - r_i and the charge-dipole potential takes the origin
712     !! as the point dipole, which is atom j in this case.
713    
714     dudx = dudx - sw*pref*( ri3*(uz_j(1) - 3.0d0*ct_j*xhat) - &
715     preRF2*uz_j(1) )
716     dudy = dudy - sw*pref*( ri3*(uz_j(2) - 3.0d0*ct_j*yhat) - &
717     preRF2*uz_j(2) )
718     dudz = dudz - sw*pref*( ri3*(uz_j(3) - 3.0d0*ct_j*zhat) - &
719     preRF2*uz_j(3) )
720     duduz_j(1) = duduz_j(1) - sw*pref * xhat * ( ri2 - preRF2*rij )
721     duduz_j(2) = duduz_j(2) - sw*pref * yhat * ( ri2 - preRF2*rij )
722     duduz_j(3) = duduz_j(3) - sw*pref * zhat * ( ri2 - preRF2*rij )
723    
724 chrisfen 2296 else
725     if (j_is_SplitDipole) then
726     BigR = sqrt(r2 + 0.25_dp * d_j * d_j)
727     ri = 1.0_dp / BigR
728     scale = rij * ri
729     else
730     ri = riji
731     scale = 1.0_dp
732     endif
733    
734     ri2 = ri * ri
735     ri3 = ri2 * ri
736     sc2 = scale * scale
737 chrisfen 2325
738 chrisfen 2548 pot_term = ri2 * scale * f1
739     vterm = - pref * ct_j * pot_term
740 chrisfen 2325 vpair = vpair + vterm
741     epot = epot + sw*vterm
742 chrisfen 2296
743     !! this has a + sign in the () because the rij vector is
744     !! r_j - r_i and the charge-dipole potential takes the origin
745     !! as the point dipole, which is atom j in this case.
746    
747 chrisfen 2548 dudx = dudx - sw*pref * ri3 * ( uz_j(1)*f1 - &
748     ct_j*xhat*sc2*( 3.0d0*f1 + f3 ) )
749     dudy = dudy - sw*pref * ri3 * ( uz_j(2)*f1 - &
750     ct_j*yhat*sc2*( 3.0d0*f1 + f3 ) )
751     dudz = dudz - sw*pref * ri3 * ( uz_j(3)*f1 - &
752     ct_j*zhat*sc2*( 3.0d0*f1 + f3 ) )
753    
754     duduz_j(1) = duduz_j(1) - sw*pref * pot_term * xhat
755     duduz_j(2) = duduz_j(2) - sw*pref * pot_term * yhat
756     duduz_j(3) = duduz_j(3) - sw*pref * pot_term * zhat
757 gezelter 2095
758 chrisfen 2296 endif
759 gezelter 2095 endif
760 gezelter 2105
761 gezelter 2123 if (j_is_Quadrupole) then
762 chrisfen 2548 if (screeningMethod .eq. DAMPED) then
763     f0 = derfc(dampingAlpha*rij)
764     varEXP = exp(-alpha2*rij*rij)
765     f1 = alphaPi*rij*varEXP + f0
766     f2 = alphaPi*2.0d0*alpha2*varEXP
767     f3 = f2*rij*rij*rij
768     f4 = 2.0d0*alpha2*f2*rij
769     endif
770    
771 gezelter 2123 ri2 = riji * riji
772     ri3 = ri2 * riji
773 gezelter 2124 ri4 = ri2 * ri2
774 gezelter 2123 cx2 = cx_j * cx_j
775     cy2 = cy_j * cy_j
776     cz2 = cz_j * cz_j
777    
778 chrisfen 2439 pref = pre14 * q_i / 3.0_dp
779 chrisfen 2548 pot_term = ri3*(qxx_j * (3.0_dp*cx2 - 1.0_dp) + &
780 chrisfen 2439 qyy_j * (3.0_dp*cy2 - 1.0_dp) + &
781     qzz_j * (3.0_dp*cz2 - 1.0_dp))
782 chrisfen 2548 vterm = pref * (pot_term*f1 + (qxx_j*cx2 + qyy_j*cy2 + qzz_j*cz2)*f2)
783 chrisfen 2439 vpair = vpair + vterm
784     epot = epot + sw*vterm
785 chrisfen 2296
786 chrisfen 2548 dudx = dudx - sw*pref*pot_term*riji*xhat*(5.0d0*f1 + f3) + &
787     sw*pref*ri4 * ( &
788     qxx_j*(2.0_dp*cx_j*ux_j(1)*(3.0d0*f1 + f3) - 2.0_dp*xhat*f1) + &
789     qyy_j*(2.0_dp*cy_j*uy_j(1)*(3.0d0*f1 + f3) - 2.0_dp*xhat*f1) + &
790     qzz_j*(2.0_dp*cz_j*uz_j(1)*(3.0d0*f1 + f3) - 2.0_dp*xhat*f1) ) &
791     + (qxx_j*cx2 + qyy_j*cy2 + qzz_j*cz2)*f4
792     dudy = dudy - sw*pref*pot_term*riji*yhat*(5.0d0*f1 + f3) + &
793     sw*pref*ri4 * ( &
794     qxx_j*(2.0_dp*cx_j*ux_j(2)*(3.0d0*f1 + f3) - 2.0_dp*yhat*f1) + &
795     qyy_j*(2.0_dp*cy_j*uy_j(2)*(3.0d0*f1 + f3) - 2.0_dp*yhat*f1) + &
796     qzz_j*(2.0_dp*cz_j*uz_j(2)*(3.0d0*f1 + f3) - 2.0_dp*yhat*f1) ) &
797     + (qxx_j*cx2 + qyy_j*cy2 + qzz_j*cz2)*f4
798     dudz = dudz - sw*pref*pot_term*riji*zhat*(5.0d0*f1 + f3) + &
799     sw*pref*ri4 * ( &
800     qxx_j*(2.0_dp*cx_j*ux_j(3)*(3.0d0*f1 + f3) - 2.0_dp*zhat*f1) + &
801     qyy_j*(2.0_dp*cy_j*uy_j(3)*(3.0d0*f1 + f3) - 2.0_dp*zhat*f1) + &
802     qzz_j*(2.0_dp*cz_j*uz_j(3)*(3.0d0*f1 + f3) - 2.0_dp*zhat*f1) ) &
803     + (qxx_j*cx2 + qyy_j*cy2 + qzz_j*cz2)*f4
804 chrisfen 2439
805 chrisfen 2548 dudux_j(1) = dudux_j(1) + sw*pref*ri3*( (qxx_j*2.0_dp*cx_j*xhat) &
806     * (3.0d0*f1 + f3) )
807     dudux_j(2) = dudux_j(2) + sw*pref*ri3*( (qxx_j*2.0_dp*cx_j*yhat) &
808     * (3.0d0*f1 + f3) )
809     dudux_j(3) = dudux_j(3) + sw*pref*ri3*( (qxx_j*2.0_dp*cx_j*zhat) &
810     * (3.0d0*f1 + f3) )
811 chrisfen 2439
812 chrisfen 2548 duduy_j(1) = duduy_j(1) + sw*pref*ri3*( (qyy_j*2.0_dp*cy_j*xhat) &
813     * (3.0d0*f1 + f3) )
814     duduy_j(2) = duduy_j(2) + sw*pref*ri3*( (qyy_j*2.0_dp*cy_j*yhat) &
815     * (3.0d0*f1 + f3) )
816     duduy_j(3) = duduy_j(3) + sw*pref*ri3*( (qyy_j*2.0_dp*cy_j*zhat) &
817     * (3.0d0*f1 + f3) )
818 chrisfen 2439
819 chrisfen 2548 duduz_j(1) = duduz_j(1) + sw*pref*ri3*( (qzz_j*2.0_dp*cz_j*xhat) &
820     * (3.0d0*f1 + f3) )
821     duduz_j(2) = duduz_j(2) + sw*pref*ri3*( (qzz_j*2.0_dp*cz_j*yhat) &
822     * (3.0d0*f1 + f3) )
823     duduz_j(3) = duduz_j(3) + sw*pref*ri3*( (qzz_j*2.0_dp*cz_j*zhat) &
824     * (3.0d0*f1 + f3) )
825    
826 gezelter 2123 endif
827 gezelter 2095 endif
828 chrisfen 2439
829 gezelter 2095 if (i_is_Dipole) then
830 gezelter 2204
831 gezelter 2095 if (j_is_Charge) then
832 chrisfen 2548 if (screeningMethod .eq. DAMPED) then
833     f0 = derfc(dampingAlpha*rij)
834     varEXP = exp(-alpha2*rij*rij)
835     f1 = alphaPi*rij*varEXP + f0
836     f3 = alphaPi*2.0d0*alpha2*varEXP*rij*rij*rij
837     endif
838 chrisfen 2325
839 chrisfen 2439 pref = pre12 * q_j * mu_i
840    
841 chrisfen 2418 if (summationMethod .eq. SHIFTED_POTENTIAL) then
842 chrisfen 2296 ri2 = riji * riji
843     ri3 = ri2 * riji
844 chrisfen 2418
845 chrisfen 2548 pot_term = ri2*f1 - rcuti2*f1c
846 chrisfen 2418 vterm = pref * ct_i * pot_term
847     vpair = vpair + vterm
848     epot = epot + sw*vterm
849    
850 chrisfen 2548 dudx = dudx + sw*pref*( ri3*(uz_i(1)*f1-ct_i*xhat*(3.0d0*f1+f3)) )
851     dudy = dudy + sw*pref*( ri3*(uz_i(2)*f1-ct_i*yhat*(3.0d0*f1+f3)) )
852     dudz = dudz + sw*pref*( ri3*(uz_i(3)*f1-ct_i*zhat*(3.0d0*f1+f3)) )
853 chrisfen 2418
854     duduz_i(1) = duduz_i(1) + sw*pref * xhat * pot_term
855     duduz_i(2) = duduz_i(2) + sw*pref * yhat * pot_term
856     duduz_i(3) = duduz_i(3) + sw*pref * zhat * pot_term
857 gezelter 2204
858 chrisfen 2418 elseif (summationMethod .eq. SHIFTED_FORCE) then
859     ri2 = riji * riji
860     ri3 = ri2 * riji
861    
862 chrisfen 2548 !! might need a -(f1c-f0c) or dct_i/dr in the derivative term...
863     pot_term = ri2*f1 - rcuti2*f1c + &
864     (2.0d0*rcuti3*f1c + f2c)*( rij - defaultCutoff )
865 chrisfen 2418 vterm = pref * ct_i * pot_term
866     vpair = vpair + vterm
867     epot = epot + sw*vterm
868    
869 chrisfen 2548 dudx = dudx + sw*pref*( ri3*(uz_i(1)*f1-ct_i*xhat*(3.0d0*f1+f3)) &
870     - rcuti3*(uz_i(1)*f1c-ct_i*xhat*(3.0d0*f1c+f3c)) )
871     dudy = dudy + sw*pref*( ri3*(uz_i(2)*f1-ct_i*yhat*(3.0d0*f1+f3)) &
872     - rcuti3*(uz_i(1)*f1c-ct_i*xhat*(3.0d0*f1c+f3c)) )
873     dudz = dudz + sw*pref*( ri3*(uz_i(3)*f1-ct_i*zhat*(3.0d0*f1+f3)) &
874     - rcuti3*(uz_i(1)*f1c-ct_i*xhat*(3.0d0*f1c+f3c)) )
875 chrisfen 2418
876     duduz_i(1) = duduz_i(1) + sw*pref * xhat * pot_term
877     duduz_i(2) = duduz_i(2) + sw*pref * yhat * pot_term
878     duduz_i(3) = duduz_i(3) + sw*pref * zhat * pot_term
879 chrisfen 2548
880 chrisfen 2418 elseif (summationMethod .eq. REACTION_FIELD) then
881     ri2 = riji * riji
882     ri3 = ri2 * riji
883    
884 chrisfen 2399 vterm = pref * ct_i * ( ri2 - preRF2*rij )
885 chrisfen 2395 vpair = vpair + vterm
886     epot = epot + sw*vterm
887    
888 chrisfen 2399 dudx = dudx + sw*pref * ( ri3*(uz_i(1) - 3.0d0*ct_i*xhat) - &
889     preRF2*uz_i(1) )
890     dudy = dudy + sw*pref * ( ri3*(uz_i(2) - 3.0d0*ct_i*yhat) - &
891     preRF2*uz_i(2) )
892     dudz = dudz + sw*pref * ( ri3*(uz_i(3) - 3.0d0*ct_i*zhat) - &
893     preRF2*uz_i(3) )
894 chrisfen 2395
895 chrisfen 2399 duduz_i(1) = duduz_i(1) + sw*pref * xhat * ( ri2 - preRF2*rij )
896     duduz_i(2) = duduz_i(2) + sw*pref * yhat * ( ri2 - preRF2*rij )
897     duduz_i(3) = duduz_i(3) + sw*pref * zhat * ( ri2 - preRF2*rij )
898 chrisfen 2395
899 chrisfen 2296 else
900     if (i_is_SplitDipole) then
901 gezelter 2105 BigR = sqrt(r2 + 0.25_dp * d_i * d_i)
902     ri = 1.0_dp / BigR
903 chrisfen 2296 scale = rij * ri
904     else
905 gezelter 2105 ri = riji
906     scale = 1.0_dp
907     endif
908 chrisfen 2296
909     ri2 = ri * ri
910     ri3 = ri2 * ri
911     sc2 = scale * scale
912 chrisfen 2325
913 chrisfen 2548 pot_term = ri2 * f1 * scale
914     vterm = pref * ct_i * pot_term
915 chrisfen 2325 vpair = vpair + vterm
916     epot = epot + sw*vterm
917 chrisfen 2296
918 chrisfen 2548 dudx = dudx + sw*pref * ri3 * ( uz_i(1)*f1 - &
919     ct_i*xhat*sc2*( 3.0d0*f1 + f3 ) )
920     dudy = dudy + sw*pref * ri3 * ( uz_i(2)*f1 - &
921     ct_i*yhat*sc2*( 3.0d0*f1 + f3 ) )
922     dudz = dudz + sw*pref * ri3 * ( uz_i(3)*f1 - &
923     ct_i*zhat*sc2*( 3.0d0*f1 + f3 ) )
924 chrisfen 2296
925 chrisfen 2548 duduz_i(1) = duduz_i(1) + sw*pref * pot_term * xhat
926     duduz_i(2) = duduz_i(2) + sw*pref * pot_term * yhat
927     duduz_i(3) = duduz_i(3) + sw*pref * pot_term * zhat
928 gezelter 2105 endif
929 chrisfen 2296 endif
930 chrisfen 2325
931 chrisfen 2296 if (j_is_Dipole) then
932 chrisfen 2548 if (screeningMethod .eq. DAMPED) then
933     f0 = derfc(dampingAlpha*rij)
934     varEXP = exp(-alpha2*rij*rij)
935     f1 = alphaPi*rij*varEXP + f0
936     f2 = alphaPi*2.0d0*alpha2*varEXP
937     f3 = f2*rij*rij*rij
938     f4 = 2.0d0*alpha2*f3*rij*rij
939     endif
940    
941 chrisfen 2418 ct_ij = uz_i(1)*uz_j(1) + uz_i(2)*uz_j(2) + uz_i(3)*uz_j(3)
942    
943     ri2 = riji * riji
944     ri3 = ri2 * riji
945     ri4 = ri2 * ri2
946    
947     pref = pre22 * mu_i * mu_j
948 gezelter 2105
949 chrisfen 2409 if (summationMethod .eq. REACTION_FIELD) then
950 chrisfen 2394 vterm = pref*( ri3*(ct_ij - 3.0d0 * ct_i * ct_j) - &
951     preRF2*ct_ij )
952     vpair = vpair + vterm
953     epot = epot + sw*vterm
954    
955     a1 = 5.0d0 * ct_i * ct_j - ct_ij
956    
957     dudx = dudx + sw*pref*3.0d0*ri4 &
958     * (a1*xhat-ct_i*uz_j(1)-ct_j*uz_i(1))
959     dudy = dudy + sw*pref*3.0d0*ri4 &
960     * (a1*yhat-ct_i*uz_j(2)-ct_j*uz_i(2))
961     dudz = dudz + sw*pref*3.0d0*ri4 &
962     * (a1*zhat-ct_i*uz_j(3)-ct_j*uz_i(3))
963    
964     duduz_i(1) = duduz_i(1) + sw*pref*(ri3*(uz_j(1)-3.0d0*ct_j*xhat) &
965     - preRF2*uz_j(1))
966     duduz_i(2) = duduz_i(2) + sw*pref*(ri3*(uz_j(2)-3.0d0*ct_j*yhat) &
967     - preRF2*uz_j(2))
968     duduz_i(3) = duduz_i(3) + sw*pref*(ri3*(uz_j(3)-3.0d0*ct_j*zhat) &
969     - preRF2*uz_j(3))
970     duduz_j(1) = duduz_j(1) + sw*pref*(ri3*(uz_i(1)-3.0d0*ct_i*xhat) &
971     - preRF2*uz_i(1))
972     duduz_j(2) = duduz_j(2) + sw*pref*(ri3*(uz_i(2)-3.0d0*ct_i*yhat) &
973     - preRF2*uz_i(2))
974     duduz_j(3) = duduz_j(3) + sw*pref*(ri3*(uz_i(3)-3.0d0*ct_i*zhat) &
975     - preRF2*uz_i(3))
976    
977 chrisfen 2296 else
978     if (i_is_SplitDipole) then
979     if (j_is_SplitDipole) then
980     BigR = sqrt(r2 + 0.25_dp * d_i * d_i + 0.25_dp * d_j * d_j)
981     else
982     BigR = sqrt(r2 + 0.25_dp * d_i * d_i)
983     endif
984     ri = 1.0_dp / BigR
985     scale = rij * ri
986     else
987     if (j_is_SplitDipole) then
988     BigR = sqrt(r2 + 0.25_dp * d_j * d_j)
989     ri = 1.0_dp / BigR
990     scale = rij * ri
991     else
992     ri = riji
993     scale = 1.0_dp
994     endif
995     endif
996    
997     sc2 = scale * scale
998 chrisfen 2418
999 chrisfen 2548 pot_term = (ct_ij - 3.0d0 * ct_i * ct_j * sc2)
1000     vterm = pref * ( ri3*pot_term*f1 + (ct_i * ct_j)*f2 )
1001 chrisfen 2325 vpair = vpair + vterm
1002     epot = epot + sw*vterm
1003 chrisfen 2296
1004 chrisfen 2548 f13 = f1+f3
1005     f134 = f13 + f4
1006 chrisfen 2296
1007 chrisfen 2548 !!$ dudx = dudx + sw*pref * ( ri4*scale*( &
1008     !!$ 3.0d0*(a1*xhat-ct_i*uz_j(1)-ct_j*uz_i(1))*f1 &
1009     !!$ - pot_term*f3) &
1010     !!$ + 2.0d0*ct_i*ct_j*xhat*(ct_i*uz_j(1)+ct_j*uz_i(1))*f3 &
1011     !!$ + (ct_i * ct_j)*f4 )
1012     !!$ dudy = dudy + sw*pref * ( ri4*scale*( &
1013     !!$ 3.0d0*(a1*yhat-ct_i*uz_j(2)-ct_j*uz_i(2))*f1 &
1014     !!$ - pot_term*f3) &
1015     !!$ + 2.0d0*ct_i*ct_j*yhat*(ct_i*uz_j(2)+ct_j*uz_i(2))*f3 &
1016     !!$ + (ct_i * ct_j)*f4 )
1017     !!$ dudz = dudz + sw*pref * ( ri4*scale*( &
1018     !!$ 3.0d0*(a1*zhat-ct_i*uz_j(3)-ct_j*uz_i(3))*f1 &
1019     !!$ - pot_term*f3) &
1020     !!$ + 2.0d0*ct_i*ct_j*zhat*(ct_i*uz_j(3)+ct_j*uz_i(3))*f3 &
1021     !!$ + (ct_i * ct_j)*f4 )
1022    
1023     dudx = dudx + sw*pref * ( ri4*scale*( &
1024     15.0d0*(ct_i * ct_j * sc2)*xhat*f134 - &
1025     3.0d0*(ct_i*uz_j(1) + ct_j*uz_i(1) + ct_ij*xhat)*f134) )
1026     dudy = dudy + sw*pref * ( ri4*scale*( &
1027     15.0d0*(ct_i * ct_j * sc2)*yhat*f134 - &
1028     3.0d0*(ct_i*uz_j(2) + ct_j*uz_i(2) + ct_ij*yhat)*f134) )
1029     dudz = dudz + sw*pref * ( ri4*scale*( &
1030     15.0d0*(ct_i * ct_j * sc2)*zhat*f134 - &
1031     3.0d0*(ct_i*uz_j(3) + ct_j*uz_i(3) + ct_ij*zhat)*f134) )
1032 chrisfen 2296
1033 chrisfen 2548 duduz_i(1) = duduz_i(1) + sw*pref * &
1034     ( ri3*(uz_j(1) - 3.0d0*ct_j*xhat*sc2)*f1 + (ct_j*xhat)*f2 )
1035     duduz_i(2) = duduz_i(2) + sw*pref * &
1036     ( ri3*(uz_j(2) - 3.0d0*ct_j*yhat*sc2)*f1 + (ct_j*yhat)*f2 )
1037     duduz_i(3) = duduz_i(3) + sw*pref * &
1038     ( ri3*(uz_j(3) - 3.0d0*ct_j*zhat*sc2)*f1 + (ct_j*zhat)*f2 )
1039 chrisfen 2296
1040 chrisfen 2548 duduz_j(1) = duduz_j(1) + sw*pref * &
1041     ( ri3*(uz_i(1) - 3.0d0*ct_i*xhat*sc2)*f1 + (ct_i*xhat)*f2 )
1042     duduz_j(2) = duduz_j(2) + sw*pref * &
1043     ( ri3*(uz_i(2) - 3.0d0*ct_i*yhat*sc2)*f1 + (ct_i*yhat)*f2 )
1044     duduz_j(3) = duduz_j(3) + sw*pref * &
1045     ( ri3*(uz_i(3) - 3.0d0*ct_i*zhat*sc2)*f1 + (ct_i*zhat)*f2 )
1046 chrisfen 2296 endif
1047 gezelter 2095 endif
1048     endif
1049 gezelter 2123
1050     if (i_is_Quadrupole) then
1051     if (j_is_Charge) then
1052 chrisfen 2548 if (screeningMethod .eq. DAMPED) then
1053     f0 = derfc(dampingAlpha*rij)
1054     varEXP = exp(-alpha2*rij*rij)
1055     f1 = alphaPi*rij*varEXP + f0
1056     f2 = alphaPi*2.0d0*alpha2*varEXP
1057     f3 = f2*rij*rij*rij
1058     f4 = 2.0d0*alpha2*f2*rij
1059     endif
1060    
1061 gezelter 2123 ri2 = riji * riji
1062     ri3 = ri2 * riji
1063 gezelter 2124 ri4 = ri2 * ri2
1064 gezelter 2123 cx2 = cx_i * cx_i
1065     cy2 = cy_i * cy_i
1066     cz2 = cz_i * cz_i
1067 gezelter 2204
1068 chrisfen 2439 pref = pre14 * q_j / 3.0_dp
1069 chrisfen 2548 pot_term = ri3 * (qxx_i * (3.0_dp*cx2 - 1.0_dp) + &
1070     qyy_i * (3.0_dp*cy2 - 1.0_dp) + &
1071     qzz_i * (3.0_dp*cz2 - 1.0_dp))
1072     vterm = pref * (pot_term*f1 + (qxx_i*cx2 + qyy_i*cy2 + qzz_i*cz2)*f2)
1073 chrisfen 2439 vpair = vpair + vterm
1074     epot = epot + sw*vterm
1075    
1076 chrisfen 2548 dudx = dudx - sw*pref*pot_term*riji*xhat*(5.0d0*f1 + f3) + &
1077     sw*pref*ri4 * ( &
1078     qxx_i*(2.0_dp*cx_i*ux_i(1)*(3.0d0*f1 + f3) - 2.0_dp*xhat*f1) + &
1079     qyy_i*(2.0_dp*cy_i*uy_i(1)*(3.0d0*f1 + f3) - 2.0_dp*xhat*f1) + &
1080     qzz_i*(2.0_dp*cz_i*uz_i(1)*(3.0d0*f1 + f3) - 2.0_dp*xhat*f1) ) &
1081     + (qxx_i*cx2 + qyy_i*cy2 + qzz_i*cz2)*f4
1082     dudy = dudy - sw*pref*pot_term*riji*yhat*(5.0d0*f1 + f3) + &
1083     sw*pref*ri4 * ( &
1084     qxx_i*(2.0_dp*cx_i*ux_i(2)*(3.0d0*f1 + f3) - 2.0_dp*yhat*f1) + &
1085     qyy_i*(2.0_dp*cy_i*uy_i(2)*(3.0d0*f1 + f3) - 2.0_dp*yhat*f1) + &
1086     qzz_i*(2.0_dp*cz_i*uz_i(2)*(3.0d0*f1 + f3) - 2.0_dp*yhat*f1) ) &
1087     + (qxx_i*cx2 + qyy_i*cy2 + qzz_i*cz2)*f4
1088     dudz = dudz - sw*pref*pot_term*riji*zhat*(5.0d0*f1 + f3) + &
1089     sw*pref*ri4 * ( &
1090     qxx_i*(2.0_dp*cx_i*ux_i(3)*(3.0d0*f1 + f3) - 2.0_dp*zhat*f1) + &
1091     qyy_i*(2.0_dp*cy_i*uy_i(3)*(3.0d0*f1 + f3) - 2.0_dp*zhat*f1) + &
1092     qzz_i*(2.0_dp*cz_i*uz_i(3)*(3.0d0*f1 + f3) - 2.0_dp*zhat*f1) ) &
1093     + (qxx_i*cx2 + qyy_i*cy2 + qzz_i*cz2)*f4
1094 chrisfen 2439
1095 chrisfen 2548 dudux_i(1) = dudux_i(1) + sw*pref*( ri3*(qxx_i*2.0_dp*cx_i*xhat) &
1096     * (3.0d0*f1 + f3) )
1097     dudux_i(2) = dudux_i(2) + sw*pref*( ri3*(qxx_i*2.0_dp*cx_i*yhat) &
1098     * (3.0d0*f1 + f3) )
1099     dudux_i(3) = dudux_i(3) + sw*pref*( ri3*(qxx_i*2.0_dp*cx_i*zhat) &
1100     * (3.0d0*f1 + f3) )
1101 chrisfen 2439
1102 chrisfen 2548 duduy_i(1) = duduy_i(1) + sw*pref*( ri3*(qyy_i*2.0_dp*cy_i*xhat) &
1103     * (3.0d0*f1 + f3) )
1104     duduy_i(2) = duduy_i(2) + sw*pref*( ri3*(qyy_i*2.0_dp*cy_i*yhat) &
1105     * (3.0d0*f1 + f3) )
1106     duduy_i(3) = duduy_i(3) + sw*pref*( ri3*(qyy_i*2.0_dp*cy_i*zhat) &
1107     * (3.0d0*f1 + f3) )
1108 chrisfen 2439
1109 chrisfen 2548 duduz_i(1) = duduz_i(1) + sw*pref*( ri3*(qzz_i*2.0_dp*cz_i*xhat) &
1110     * (3.0d0*f1 + f3) )
1111     duduz_i(2) = duduz_i(2) + sw*pref*( ri3*(qzz_i*2.0_dp*cz_i*yhat) &
1112     * (3.0d0*f1 + f3) )
1113     duduz_i(3) = duduz_i(3) + sw*pref*( ri3*(qzz_i*2.0_dp*cz_i*zhat) &
1114     * (3.0d0*f1 + f3) )
1115 chrisfen 2439
1116 gezelter 2123 endif
1117     endif
1118 gezelter 2204
1119    
1120 gezelter 2095 if (do_pot) then
1121     #ifdef IS_MPI
1122 chuckv 2355 pot_row(ELECTROSTATIC_POT,atom1) = pot_row(ELECTROSTATIC_POT,atom1) + 0.5d0*epot
1123     pot_col(ELECTROSTATIC_POT,atom2) = pot_col(ELECTROSTATIC_POT,atom2) + 0.5d0*epot
1124 gezelter 2095 #else
1125     pot = pot + epot
1126     #endif
1127     endif
1128 gezelter 2204
1129 gezelter 2095 #ifdef IS_MPI
1130     f_Row(1,atom1) = f_Row(1,atom1) + dudx
1131     f_Row(2,atom1) = f_Row(2,atom1) + dudy
1132     f_Row(3,atom1) = f_Row(3,atom1) + dudz
1133 gezelter 2204
1134 gezelter 2095 f_Col(1,atom2) = f_Col(1,atom2) - dudx
1135     f_Col(2,atom2) = f_Col(2,atom2) - dudy
1136     f_Col(3,atom2) = f_Col(3,atom2) - dudz
1137 gezelter 2204
1138 gezelter 2095 if (i_is_Dipole .or. i_is_Quadrupole) then
1139 gezelter 2123 t_Row(1,atom1)=t_Row(1,atom1) - uz_i(2)*duduz_i(3) + uz_i(3)*duduz_i(2)
1140     t_Row(2,atom1)=t_Row(2,atom1) - uz_i(3)*duduz_i(1) + uz_i(1)*duduz_i(3)
1141     t_Row(3,atom1)=t_Row(3,atom1) - uz_i(1)*duduz_i(2) + uz_i(2)*duduz_i(1)
1142 gezelter 2095 endif
1143 gezelter 2123 if (i_is_Quadrupole) then
1144     t_Row(1,atom1)=t_Row(1,atom1) - ux_i(2)*dudux_i(3) + ux_i(3)*dudux_i(2)
1145     t_Row(2,atom1)=t_Row(2,atom1) - ux_i(3)*dudux_i(1) + ux_i(1)*dudux_i(3)
1146     t_Row(3,atom1)=t_Row(3,atom1) - ux_i(1)*dudux_i(2) + ux_i(2)*dudux_i(1)
1147 gezelter 2095
1148 gezelter 2123 t_Row(1,atom1)=t_Row(1,atom1) - uy_i(2)*duduy_i(3) + uy_i(3)*duduy_i(2)
1149     t_Row(2,atom1)=t_Row(2,atom1) - uy_i(3)*duduy_i(1) + uy_i(1)*duduy_i(3)
1150     t_Row(3,atom1)=t_Row(3,atom1) - uy_i(1)*duduy_i(2) + uy_i(2)*duduy_i(1)
1151     endif
1152    
1153 gezelter 2095 if (j_is_Dipole .or. j_is_Quadrupole) then
1154 gezelter 2123 t_Col(1,atom2)=t_Col(1,atom2) - uz_j(2)*duduz_j(3) + uz_j(3)*duduz_j(2)
1155     t_Col(2,atom2)=t_Col(2,atom2) - uz_j(3)*duduz_j(1) + uz_j(1)*duduz_j(3)
1156     t_Col(3,atom2)=t_Col(3,atom2) - uz_j(1)*duduz_j(2) + uz_j(2)*duduz_j(1)
1157 gezelter 2095 endif
1158 gezelter 2123 if (j_is_Quadrupole) then
1159     t_Col(1,atom2)=t_Col(1,atom2) - ux_j(2)*dudux_j(3) + ux_j(3)*dudux_j(2)
1160     t_Col(2,atom2)=t_Col(2,atom2) - ux_j(3)*dudux_j(1) + ux_j(1)*dudux_j(3)
1161     t_Col(3,atom2)=t_Col(3,atom2) - ux_j(1)*dudux_j(2) + ux_j(2)*dudux_j(1)
1162 gezelter 2095
1163 gezelter 2123 t_Col(1,atom2)=t_Col(1,atom2) - uy_j(2)*duduy_j(3) + uy_j(3)*duduy_j(2)
1164     t_Col(2,atom2)=t_Col(2,atom2) - uy_j(3)*duduy_j(1) + uy_j(1)*duduy_j(3)
1165     t_Col(3,atom2)=t_Col(3,atom2) - uy_j(1)*duduy_j(2) + uy_j(2)*duduy_j(1)
1166     endif
1167    
1168 gezelter 2095 #else
1169     f(1,atom1) = f(1,atom1) + dudx
1170     f(2,atom1) = f(2,atom1) + dudy
1171     f(3,atom1) = f(3,atom1) + dudz
1172 gezelter 2204
1173 gezelter 2095 f(1,atom2) = f(1,atom2) - dudx
1174     f(2,atom2) = f(2,atom2) - dudy
1175     f(3,atom2) = f(3,atom2) - dudz
1176 gezelter 2204
1177 gezelter 2095 if (i_is_Dipole .or. i_is_Quadrupole) then
1178 gezelter 2123 t(1,atom1)=t(1,atom1) - uz_i(2)*duduz_i(3) + uz_i(3)*duduz_i(2)
1179     t(2,atom1)=t(2,atom1) - uz_i(3)*duduz_i(1) + uz_i(1)*duduz_i(3)
1180     t(3,atom1)=t(3,atom1) - uz_i(1)*duduz_i(2) + uz_i(2)*duduz_i(1)
1181 gezelter 2095 endif
1182 gezelter 2123 if (i_is_Quadrupole) then
1183     t(1,atom1)=t(1,atom1) - ux_i(2)*dudux_i(3) + ux_i(3)*dudux_i(2)
1184     t(2,atom1)=t(2,atom1) - ux_i(3)*dudux_i(1) + ux_i(1)*dudux_i(3)
1185     t(3,atom1)=t(3,atom1) - ux_i(1)*dudux_i(2) + ux_i(2)*dudux_i(1)
1186    
1187     t(1,atom1)=t(1,atom1) - uy_i(2)*duduy_i(3) + uy_i(3)*duduy_i(2)
1188     t(2,atom1)=t(2,atom1) - uy_i(3)*duduy_i(1) + uy_i(1)*duduy_i(3)
1189     t(3,atom1)=t(3,atom1) - uy_i(1)*duduy_i(2) + uy_i(2)*duduy_i(1)
1190     endif
1191    
1192 gezelter 2095 if (j_is_Dipole .or. j_is_Quadrupole) then
1193 gezelter 2123 t(1,atom2)=t(1,atom2) - uz_j(2)*duduz_j(3) + uz_j(3)*duduz_j(2)
1194     t(2,atom2)=t(2,atom2) - uz_j(3)*duduz_j(1) + uz_j(1)*duduz_j(3)
1195     t(3,atom2)=t(3,atom2) - uz_j(1)*duduz_j(2) + uz_j(2)*duduz_j(1)
1196 gezelter 2095 endif
1197 gezelter 2123 if (j_is_Quadrupole) then
1198     t(1,atom2)=t(1,atom2) - ux_j(2)*dudux_j(3) + ux_j(3)*dudux_j(2)
1199     t(2,atom2)=t(2,atom2) - ux_j(3)*dudux_j(1) + ux_j(1)*dudux_j(3)
1200     t(3,atom2)=t(3,atom2) - ux_j(1)*dudux_j(2) + ux_j(2)*dudux_j(1)
1201    
1202     t(1,atom2)=t(1,atom2) - uy_j(2)*duduy_j(3) + uy_j(3)*duduy_j(2)
1203     t(2,atom2)=t(2,atom2) - uy_j(3)*duduy_j(1) + uy_j(1)*duduy_j(3)
1204     t(3,atom2)=t(3,atom2) - uy_j(1)*duduy_j(2) + uy_j(2)*duduy_j(1)
1205     endif
1206    
1207 gezelter 2095 #endif
1208 gezelter 2204
1209 gezelter 2095 #ifdef IS_MPI
1210     id1 = AtomRowToGlobal(atom1)
1211     id2 = AtomColToGlobal(atom2)
1212     #else
1213     id1 = atom1
1214     id2 = atom2
1215     #endif
1216    
1217     if (molMembershipList(id1) .ne. molMembershipList(id2)) then
1218 gezelter 2204
1219 gezelter 2095 fpair(1) = fpair(1) + dudx
1220     fpair(2) = fpair(2) + dudy
1221     fpair(3) = fpair(3) + dudz
1222    
1223     endif
1224    
1225     return
1226     end subroutine doElectrostaticPair
1227 chuckv 2189
1228     subroutine destroyElectrostaticTypes()
1229    
1230 gezelter 2204 if(allocated(ElectrostaticMap)) deallocate(ElectrostaticMap)
1231    
1232 chuckv 2189 end subroutine destroyElectrostaticTypes
1233    
1234 chrisfen 2402 subroutine self_self(atom1, eFrame, mypot, t, do_pot)
1235 chrisfen 2394 logical, intent(in) :: do_pot
1236 chrisfen 2381 integer, intent(in) :: atom1
1237 chrisfen 2394 integer :: atid1
1238 chrisfen 2381 real(kind=dp), dimension(9,nLocal) :: eFrame
1239 chrisfen 2394 real(kind=dp), dimension(3,nLocal) :: t
1240 chrisfen 2402 real(kind=dp) :: mu1, c1
1241     real(kind=dp) :: preVal, epot, mypot
1242 chrisfen 2394 real(kind=dp) :: eix, eiy, eiz
1243 chrisfen 2381
1244 chrisfen 2394 ! this is a local only array, so we use the local atom type id's:
1245     atid1 = atid(atom1)
1246 chrisfen 2402
1247     if (.not.summationMethodChecked) then
1248     call checkSummationMethod()
1249     endif
1250 chrisfen 2394
1251 chrisfen 2402 if (summationMethod .eq. REACTION_FIELD) then
1252     if (ElectrostaticMap(atid1)%is_Dipole) then
1253     mu1 = getDipoleMoment(atid1)
1254    
1255     preVal = pre22 * preRF2 * mu1*mu1
1256     mypot = mypot - 0.5d0*preVal
1257    
1258     ! The self-correction term adds into the reaction field vector
1259    
1260     eix = preVal * eFrame(3,atom1)
1261     eiy = preVal * eFrame(6,atom1)
1262     eiz = preVal * eFrame(9,atom1)
1263    
1264     ! once again, this is self-self, so only the local arrays are needed
1265     ! even for MPI jobs:
1266    
1267     t(1,atom1)=t(1,atom1) - eFrame(6,atom1)*eiz + &
1268     eFrame(9,atom1)*eiy
1269     t(2,atom1)=t(2,atom1) - eFrame(9,atom1)*eix + &
1270     eFrame(3,atom1)*eiz
1271     t(3,atom1)=t(3,atom1) - eFrame(3,atom1)*eiy + &
1272     eFrame(6,atom1)*eix
1273    
1274     endif
1275    
1276 chrisfen 2442 elseif ( (summationMethod .eq. SHIFTED_FORCE) .or. &
1277     (summationMethod .eq. SHIFTED_POTENTIAL) ) then
1278 chrisfen 2416 if (ElectrostaticMap(atid1)%is_Charge) then
1279     c1 = getCharge(atid1)
1280    
1281     if (screeningMethod .eq. DAMPED) then
1282     mypot = mypot - (f0c * rcuti * 0.5_dp + &
1283     dampingAlpha*invRootPi) * c1 * c1
1284    
1285     else
1286     mypot = mypot - (rcuti * 0.5_dp * c1 * c1)
1287    
1288     endif
1289     endif
1290     endif
1291 chrisfen 2394
1292 chrisfen 2381 return
1293 chrisfen 2402 end subroutine self_self
1294 chrisfen 2381
1295 chrisfen 2402 subroutine rf_self_excludes(atom1, atom2, sw, eFrame, d, rij, vpair, myPot, &
1296 chrisfen 2399 f, t, do_pot)
1297     logical, intent(in) :: do_pot
1298     integer, intent(in) :: atom1
1299     integer, intent(in) :: atom2
1300     logical :: i_is_Charge, j_is_Charge
1301     logical :: i_is_Dipole, j_is_Dipole
1302     integer :: atid1
1303     integer :: atid2
1304     real(kind=dp), intent(in) :: rij
1305     real(kind=dp), intent(in) :: sw
1306     real(kind=dp), intent(in), dimension(3) :: d
1307     real(kind=dp), intent(inout) :: vpair
1308     real(kind=dp), dimension(9,nLocal) :: eFrame
1309     real(kind=dp), dimension(3,nLocal) :: f
1310     real(kind=dp), dimension(3,nLocal) :: t
1311     real (kind = dp), dimension(3) :: duduz_i
1312     real (kind = dp), dimension(3) :: duduz_j
1313     real (kind = dp), dimension(3) :: uz_i
1314     real (kind = dp), dimension(3) :: uz_j
1315     real(kind=dp) :: q_i, q_j, mu_i, mu_j
1316     real(kind=dp) :: xhat, yhat, zhat
1317     real(kind=dp) :: ct_i, ct_j
1318     real(kind=dp) :: ri2, ri3, riji, vterm
1319 chrisfen 2402 real(kind=dp) :: pref, preVal, rfVal, myPot
1320 chrisfen 2399 real(kind=dp) :: dudx, dudy, dudz, dudr
1321    
1322 chrisfen 2402 if (.not.summationMethodChecked) then
1323     call checkSummationMethod()
1324 chrisfen 2399 endif
1325    
1326     dudx = 0.0d0
1327     dudy = 0.0d0
1328     dudz = 0.0d0
1329    
1330     riji = 1.0d0/rij
1331    
1332     xhat = d(1) * riji
1333     yhat = d(2) * riji
1334     zhat = d(3) * riji
1335    
1336     ! this is a local only array, so we use the local atom type id's:
1337     atid1 = atid(atom1)
1338     atid2 = atid(atom2)
1339     i_is_Charge = ElectrostaticMap(atid1)%is_Charge
1340     j_is_Charge = ElectrostaticMap(atid2)%is_Charge
1341     i_is_Dipole = ElectrostaticMap(atid1)%is_Dipole
1342     j_is_Dipole = ElectrostaticMap(atid2)%is_Dipole
1343    
1344     if (i_is_Charge.and.j_is_Charge) then
1345     q_i = ElectrostaticMap(atid1)%charge
1346     q_j = ElectrostaticMap(atid2)%charge
1347    
1348     preVal = pre11 * q_i * q_j
1349     rfVal = preRF*rij*rij
1350     vterm = preVal * rfVal
1351    
1352 chrisfen 2402 myPot = myPot + sw*vterm
1353    
1354 chrisfen 2399 dudr = sw*preVal * 2.0d0*rfVal*riji
1355 chrisfen 2402
1356 chrisfen 2399 dudx = dudx + dudr * xhat
1357     dudy = dudy + dudr * yhat
1358     dudz = dudz + dudr * zhat
1359 chrisfen 2402
1360 chrisfen 2399 elseif (i_is_Charge.and.j_is_Dipole) then
1361     q_i = ElectrostaticMap(atid1)%charge
1362     mu_j = ElectrostaticMap(atid2)%dipole_moment
1363     uz_j(1) = eFrame(3,atom2)
1364     uz_j(2) = eFrame(6,atom2)
1365     uz_j(3) = eFrame(9,atom2)
1366     ct_j = uz_j(1)*xhat + uz_j(2)*yhat + uz_j(3)*zhat
1367 chrisfen 2402
1368 chrisfen 2399 ri2 = riji * riji
1369     ri3 = ri2 * riji
1370    
1371     pref = pre12 * q_i * mu_j
1372     vterm = - pref * ct_j * ( ri2 - preRF2*rij )
1373 chrisfen 2402 myPot = myPot + sw*vterm
1374    
1375     dudx = dudx - sw*pref*( ri3*(uz_j(1)-3.0d0*ct_j*xhat) &
1376     - preRF2*uz_j(1) )
1377     dudy = dudy - sw*pref*( ri3*(uz_j(2)-3.0d0*ct_j*yhat) &
1378     - preRF2*uz_j(2) )
1379     dudz = dudz - sw*pref*( ri3*(uz_j(3)-3.0d0*ct_j*zhat) &
1380     - preRF2*uz_j(3) )
1381    
1382 chrisfen 2399 duduz_j(1) = duduz_j(1) - sw * pref * xhat * ( ri2 - preRF2*rij )
1383     duduz_j(2) = duduz_j(2) - sw * pref * yhat * ( ri2 - preRF2*rij )
1384     duduz_j(3) = duduz_j(3) - sw * pref * zhat * ( ri2 - preRF2*rij )
1385 chrisfen 2402
1386 chrisfen 2399 elseif (i_is_Dipole.and.j_is_Charge) then
1387     mu_i = ElectrostaticMap(atid1)%dipole_moment
1388     q_j = ElectrostaticMap(atid2)%charge
1389     uz_i(1) = eFrame(3,atom1)
1390     uz_i(2) = eFrame(6,atom1)
1391     uz_i(3) = eFrame(9,atom1)
1392     ct_i = uz_i(1)*xhat + uz_i(2)*yhat + uz_i(3)*zhat
1393 chrisfen 2402
1394 chrisfen 2399 ri2 = riji * riji
1395     ri3 = ri2 * riji
1396    
1397     pref = pre12 * q_j * mu_i
1398     vterm = pref * ct_i * ( ri2 - preRF2*rij )
1399 chrisfen 2402 myPot = myPot + sw*vterm
1400 chrisfen 2399
1401 chrisfen 2402 dudx = dudx + sw*pref*( ri3*(uz_i(1)-3.0d0*ct_i*xhat) &
1402     - preRF2*uz_i(1) )
1403     dudy = dudy + sw*pref*( ri3*(uz_i(2)-3.0d0*ct_i*yhat) &
1404     - preRF2*uz_i(2) )
1405     dudz = dudz + sw*pref*( ri3*(uz_i(3)-3.0d0*ct_i*zhat) &
1406     - preRF2*uz_i(3) )
1407 chrisfen 2399
1408     duduz_i(1) = duduz_i(1) + sw * pref * xhat * ( ri2 - preRF2*rij )
1409     duduz_i(2) = duduz_i(2) + sw * pref * yhat * ( ri2 - preRF2*rij )
1410     duduz_i(3) = duduz_i(3) + sw * pref * zhat * ( ri2 - preRF2*rij )
1411    
1412     endif
1413 chrisfen 2402
1414    
1415     ! accumulate the forces and torques resulting from the self term
1416 chrisfen 2399 f(1,atom1) = f(1,atom1) + dudx
1417     f(2,atom1) = f(2,atom1) + dudy
1418     f(3,atom1) = f(3,atom1) + dudz
1419    
1420     f(1,atom2) = f(1,atom2) - dudx
1421     f(2,atom2) = f(2,atom2) - dudy
1422     f(3,atom2) = f(3,atom2) - dudz
1423    
1424     if (i_is_Dipole) then
1425     t(1,atom1)=t(1,atom1) - uz_i(2)*duduz_i(3) + uz_i(3)*duduz_i(2)
1426     t(2,atom1)=t(2,atom1) - uz_i(3)*duduz_i(1) + uz_i(1)*duduz_i(3)
1427     t(3,atom1)=t(3,atom1) - uz_i(1)*duduz_i(2) + uz_i(2)*duduz_i(1)
1428     elseif (j_is_Dipole) then
1429     t(1,atom2)=t(1,atom2) - uz_j(2)*duduz_j(3) + uz_j(3)*duduz_j(2)
1430     t(2,atom2)=t(2,atom2) - uz_j(3)*duduz_j(1) + uz_j(1)*duduz_j(3)
1431     t(3,atom2)=t(3,atom2) - uz_j(1)*duduz_j(2) + uz_j(2)*duduz_j(1)
1432     endif
1433    
1434     return
1435     end subroutine rf_self_excludes
1436    
1437 gezelter 2095 end module electrostatic_module