ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/OpenMD/branches/development/src/UseTheForce/DarkSide/electrostatic.F90
Revision: 1465
Committed: Fri Jul 9 23:08:25 2010 UTC (14 years, 11 months ago) by chuckv
File size: 49021 byte(s)
Log Message:
Creating busticated version of OpenMD

File Contents

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

Properties

Name Value
svn:keywords Author Id Revision Date