ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/OpenMD/branches/development/src/UseTheForce/DarkSide/MetalNonMetal.F90
Revision: 1467
Committed: Sat Jul 17 15:33:03 2010 UTC (14 years, 11 months ago) by gezelter
File size: 23941 byte(s)
Log Message:
well, it compiles, but still segfaults

File Contents

# User Rev Content
1 chuckv 1168 !!
2     !! Copyright (c) 2007 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 chuckv 1168 !! notice, this list of conditions and the following disclaimer.
11     !!
12 gezelter 1390 !! 2. Redistributions in binary form must reproduce the above copyright
13 chuckv 1168 !! 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 chuckv 1168
42    
43     !! Calculates Metal-Non Metal interactions.
44     !! @author Charles F. Vardeman II
45 gezelter 1442 !! @version $Id$, $Date$, $Name: not supported by cvs2svn $, $Revision$
46 chuckv 1168
47    
48     module MetalNonMetal
49     use definitions
50     use atype_module
51     use vector_class
52     use simulation
53     use status
54     use fForceOptions
55     use force_globals
56    
57     implicit none
58     PRIVATE
59     #define __FORTRAN90
60     #include "UseTheForce/DarkSide/fInteractionMap.h"
61     #include "UseTheForce/DarkSide/fMnMInteractions.h"
62    
63     logical, save :: useGeometricDistanceMixing = .false.
64     logical, save :: haveInteractionLookup = .false.
65    
66     real(kind=DP), save :: defaultCutoff = 0.0_DP
67 chuckv 1228
68 chuckv 1168 logical, save :: defaultShiftPot = .false.
69     logical, save :: defaultShiftFrc = .false.
70     logical, save :: haveDefaultCutoff = .false.
71    
72     type :: MnMinteraction
73     integer :: metal_atid
74     integer :: nonmetal_atid
75     integer :: interaction_type
76     real(kind=dp) :: R0
77     real(kind=dp) :: D0
78     real(kind=dp) :: beta0
79     real(kind=dp) :: betaH
80 gezelter 1238 real(kind=dp) :: ca1
81     real(kind=dp) :: cb1
82 chuckv 1168 real(kind=dp) :: sigma
83     real(kind=dp) :: epsilon
84     real(kind=dp) :: rCut = 0.0_dp
85     logical :: rCutWasSet = .false.
86     logical :: shiftedPot = .false.
87     logical :: shiftedFrc = .false.
88     end type MnMinteraction
89    
90     type :: MnMinteractionMap
91     PRIVATE
92     integer :: initialCapacity = 10
93     integer :: capacityIncrement = 0
94     integer :: interactionCount = 0
95     type(MnMinteraction), pointer :: interactions(:) => null()
96     end type MnMinteractionMap
97    
98 xsun 1178 type (MnMInteractionMap), pointer :: MnM_Map
99 chuckv 1168
100     integer, allocatable, dimension(:,:) :: MnMinteractionLookup
101    
102     public :: setMnMDefaultCutoff
103     public :: addInteraction
104     public :: deleteInteractions
105     public :: MNMtype
106 chuckv 1173 public :: do_mnm_pair
107 chuckv 1168
108     contains
109    
110    
111 gezelter 1464 subroutine do_mnm_pair(atid1, atid2, D, Rij, R2, Rcut, Sw, vdwMult, &
112 gezelter 1467 Vpair, Pot, A1, A2, f1, t1, t2)
113 gezelter 1464 integer, intent(in) :: atid1, atid2
114 gezelter 1386 integer :: ljt1, ljt2
115 gezelter 1286 real( kind = dp ), intent(in) :: rij, r2, rcut, vdwMult
116 gezelter 1174 real( kind = dp ) :: pot, sw, vpair
117 gezelter 1386 real( kind = dp ), intent(inout), dimension(3) :: f1
118     real (kind=dp), intent(inout), dimension(9) :: A1, A2
119     real (kind=dp), intent(inout), dimension(3) :: t1, t2
120 gezelter 1174 real( kind = dp ), intent(in), dimension(3) :: d
121 chuckv 1168
122 chuckv 1173 integer :: interaction_id
123     integer :: interaction_type
124    
125 chuckv 1175 if(.not.haveInteractionLookup) then
126     call createInteractionLookup(MnM_MAP)
127     haveInteractionLookup =.true.
128     end if
129    
130 chuckv 1173 interaction_id = MnMinteractionLookup(atid1, atid2)
131     interaction_type = MnM_Map%interactions(interaction_id)%interaction_type
132 chuckv 1229
133 chuckv 1252 select case (interaction_type)
134 chuckv 1173 case (MNM_LENNARDJONES)
135 gezelter 1464 call calc_mnm_lennardjones(D, Rij, R2, Rcut, Sw, &
136 gezelter 1467 vdwMult, Vpair, Pot, f1, interaction_id)
137 chuckv 1173 case(MNM_REPULSIVEMORSE, MNM_SHIFTEDMORSE)
138 gezelter 1464 call calc_mnm_morse(D, Rij, R2, Rcut, Sw, vdwMult, &
139 gezelter 1467 Vpair, Pot, f1, interaction_id, interaction_type)
140 chuckv 1173 case(MNM_MAW)
141 gezelter 1464 call calc_mnm_maw(atid1, atid2, D, Rij, R2, Rcut, Sw, vdwMult, &
142 gezelter 1467 Vpair, Pot, A1, A2, f1, t1, t2, interaction_id)
143 chuckv 1229 case default
144     call handleError("MetalNonMetal","Unknown interaction type")
145 chuckv 1173 end select
146    
147     end subroutine do_mnm_pair
148    
149 gezelter 1464 subroutine calc_mnm_lennardjones(D, Rij, R2, Rcut, Sw, &
150 gezelter 1467 vdwMult,Vpair, Pot, f1, interaction_id)
151 chuckv 1173
152 gezelter 1286 real( kind = dp ), intent(in) :: rij, r2, rcut, vdwMult
153 gezelter 1174 real( kind = dp ) :: pot, sw, vpair
154 gezelter 1386 real( kind = dp ), intent(inout), dimension(3) :: f1
155 gezelter 1174 real( kind = dp ), intent(in), dimension(3) :: d
156 chuckv 1173 integer, intent(in) :: interaction_id
157    
158     ! local Variables
159     real( kind = dp ) :: drdx, drdy, drdz
160     real( kind = dp ) :: fx, fy, fz
161     real( kind = dp ) :: myPot, myPotC, myDeriv, myDerivC, ros, rcos
162     real( kind = dp ) :: pot_temp, dudr
163     real( kind = dp ) :: sigmai
164     real( kind = dp ) :: epsilon
165     logical :: isSoftCore, shiftedPot, shiftedFrc
166     integer :: id1, id2, localError
167    
168 gezelter 1174 sigmai = 1.0_dp / MnM_Map%interactions(interaction_id)%sigma
169 chuckv 1173 epsilon = MnM_Map%interactions(interaction_id)%epsilon
170     shiftedPot = MnM_Map%interactions(interaction_id)%shiftedPot
171     shiftedFrc = MnM_Map%interactions(interaction_id)%shiftedFrc
172    
173     ros = rij * sigmai
174    
175     call getLJfunc(ros, myPot, myDeriv)
176    
177     if (shiftedPot) then
178     rcos = rcut * sigmai
179     call getLJfunc(rcos, myPotC, myDerivC)
180     myDerivC = 0.0_dp
181     elseif (shiftedFrc) then
182     rcos = rcut * sigmai
183     call getLJfunc(rcos, myPotC, myDerivC)
184     myPotC = myPotC + myDerivC * (rij - rcut) * sigmai
185     else
186     myPotC = 0.0_dp
187     myDerivC = 0.0_dp
188 gezelter 1174 endif
189 chuckv 1173
190 gezelter 1286 pot_temp = vdwMult * epsilon * (myPot - myPotC)
191 chuckv 1173 vpair = vpair + pot_temp
192 gezelter 1286 dudr = sw * vdwMult * epsilon * (myDeriv - myDerivC) * sigmai
193 chuckv 1173
194     drdx = d(1) / rij
195     drdy = d(2) / rij
196     drdz = d(3) / rij
197    
198     fx = dudr * drdx
199     fy = dudr * drdy
200     fz = dudr * drdz
201 gezelter 1174
202 gezelter 1386 pot = pot + sw*pot_temp
203     f1(1) = f1(1) + fx
204     f1(2) = f1(2) + fy
205     f1(3) = f1(3) + fz
206 chuckv 1173
207 gezelter 1174 return
208 chuckv 1173 end subroutine calc_mnm_lennardjones
209    
210 gezelter 1464 subroutine calc_mnm_morse(D, Rij, R2, Rcut, Sw, vdwMult, &
211 gezelter 1467 Vpair, Pot, f1, interaction_id, interaction_type)
212 gezelter 1286 real( kind = dp ), intent(in) :: rij, r2, rcut, vdwMult
213 gezelter 1174 real( kind = dp ) :: pot, sw, vpair
214 gezelter 1386 real( kind = dp ), intent(inout), dimension(3) :: f1
215 gezelter 1174 real( kind = dp ), intent(in), dimension(3) :: d
216 chuckv 1173 integer, intent(in) :: interaction_id, interaction_type
217 gezelter 1174 logical :: shiftedPot, shiftedFrc
218 chuckv 1173
219     ! Local Variables
220     real(kind=dp) :: Beta0
221     real(kind=dp) :: R0
222     real(kind=dp) :: D0
223     real(kind=dp) :: expt
224     real(kind=dp) :: expt2
225     real(kind=dp) :: expfnc
226     real(kind=dp) :: expfnc2
227     real(kind=dp) :: D_expt
228     real(kind=dp) :: D_expt2
229     real(kind=dp) :: rcos
230     real(kind=dp) :: exptC
231     real(kind=dp) :: expt2C
232     real(kind=dp) :: expfncC
233     real(kind=dp) :: expfnc2C
234     real(kind=dp) :: D_expt2C
235     real(kind=dp) :: D_exptC
236    
237     real(kind=dp) :: myPot
238     real(kind=dp) :: myPotC
239     real(kind=dp) :: myDeriv
240     real(kind=dp) :: myDerivC
241     real(kind=dp) :: pot_temp
242     real(kind=dp) :: fx,fy,fz
243     real(kind=dp) :: drdx,drdy,drdz
244     real(kind=dp) :: dudr
245     integer :: id1,id2
246 gezelter 1174
247 chuckv 1173
248 gezelter 1174 D0 = MnM_Map%interactions(interaction_id)%D0
249     R0 = MnM_Map%interactions(interaction_id)%r0
250 chuckv 1173 Beta0 = MnM_Map%interactions(interaction_id)%Beta0
251 gezelter 1174 shiftedPot = MnM_Map%interactions(interaction_id)%shiftedPot
252     shiftedFrc = MnM_Map%interactions(interaction_id)%shiftedFrc
253    
254     ! V(r) = D_e exp(-a(r-re)(exp(-a(r-re))-2)
255    
256     expt = -beta0*(rij - R0)
257 chuckv 1173 expfnc = exp(expt)
258 gezelter 1174 expfnc2 = expfnc*expfnc
259 chuckv 1173
260 gezelter 1174 if (shiftedPot .or. shiftedFrc) then
261     exptC = -beta0*(rcut - R0)
262     expfncC = exp(exptC)
263     expfnc2C = expfncC*expfncC
264     endif
265    
266 chuckv 1173 select case (interaction_type)
267 gezelter 1174 case (MNM_SHIFTEDMORSE)
268 chuckv 1173
269 gezelter 1174 myPot = D0 * (expfnc2 - 2.0_dp * expfnc)
270     myDeriv = 2.0*D0*beta0*(expfnc - expfnc2)
271 chuckv 1173
272 gezelter 1174 if (shiftedPot) then
273     myPotC = D0 * (expfnc2C - 2.0_dp * expfncC)
274     myDerivC = 0.0_dp
275     elseif (shiftedFrc) then
276     myPotC = D0 * (expfnc2C - 2.0_dp * expfncC)
277     myDerivC = 2.0*D0*beta0*(expfnc2C - expfnc2C)
278     myPotC = myPotC + myDerivC * (rij - rcut)
279     else
280     myPotC = 0.0_dp
281     myDerivC = 0.0_dp
282     endif
283 chuckv 1173
284     case (MNM_REPULSIVEMORSE)
285    
286 gezelter 1174 myPot = D0 * expfnc2
287     myDeriv = -2.0_dp * D0 * beta0 * expfnc2
288 chuckv 1173
289 gezelter 1174 if (shiftedPot) then
290     myPotC = D0 * expfnc2C
291     myDerivC = 0.0_dp
292     elseif (shiftedFrc) then
293     myPotC = D0 * expfnc2C
294     myDerivC = -2.0_dp * D0* beta0 * expfnc2C
295     myPotC = myPotC + myDerivC * (rij - rcut)
296     else
297     myPotC = 0.0_dp
298     myDerivC = 0.0_dp
299     endif
300 chuckv 1173 end select
301    
302 gezelter 1286 pot_temp = vdwMult * (myPot - myPotC)
303 chuckv 1173 vpair = vpair + pot_temp
304 gezelter 1286 dudr = sw * vdwMult * (myDeriv - myDerivC)
305 chuckv 1173
306     drdx = d(1) / rij
307     drdy = d(2) / rij
308     drdz = d(3) / rij
309    
310     fx = dudr * drdx
311     fy = dudr * drdy
312     fz = dudr * drdz
313    
314 gezelter 1386 pot = pot + sw*pot_temp
315 chuckv 1173
316 gezelter 1386 f1(1) = f1(1) + fx
317     f1(2) = f1(2) + fy
318     f1(3) = f1(3) + fz
319 chuckv 1173
320     return
321     end subroutine calc_mnm_morse
322    
323 gezelter 1464 subroutine calc_mnm_maw(atid1, atid2, D, Rij, R2, Rcut, Sw, vdwMult, &
324 gezelter 1467 Vpair, Pot, A1, A2, f1, t1, t2, interaction_id)
325 gezelter 1286 real( kind = dp ), intent(in) :: rij, r2, rcut, vdwMult
326 gezelter 1174 real( kind = dp ) :: pot, sw, vpair
327 gezelter 1386 real( kind = dp ), intent(inout), dimension(3) :: f1
328     real (kind=dp),intent(in), dimension(9) :: A1, A2
329     real (kind=dp),intent(inout), dimension(3) :: t1, t2
330 chuckv 1173
331 gezelter 1174 real( kind = dp ), intent(in), dimension(3) :: d
332 chuckv 1173
333     integer, intent(in) :: interaction_id
334    
335 gezelter 1238 real(kind = dp) :: D0, R0, beta0, ca1, cb1, pot_temp
336 gezelter 1174 real(kind = dp) :: expt0, expfnc0, expfnc02
337     real(kind = dp) :: exptH, expfncH, expfncH2
338 chuckv 1231 real(kind = dp) :: x, y, z, x2, y2, z2, r3, r4
339     real(kind = dp) :: drdx, drdy, drdz
340     real(kind = dp) :: dvdx, dvdy, dvdz
341 gezelter 1238 real(kind = dp) :: Vang, dVangdx, dVangdy, dVangdz
342     real(kind = dp) :: dVangdux, dVangduy, dVangduz
343 chuckv 1231 real(kind = dp) :: dVmorsedr
344 chuckv 1229 real(kind = dp) :: Vmorse, dVmorsedx, dVmorsedy, dVmorsedz
345 gezelter 1386 real(kind = dp) :: ta1, b1, s
346 gezelter 1238 real(kind = dp) :: da1dx, da1dy, da1dz, da1dux, da1duy, da1duz
347     real(kind = dp) :: db1dx, db1dy, db1dz, db1dux, db1duy, db1duz
348 gezelter 1174 real(kind = dp) :: fx, fy, fz, tx, ty, tz, fxl, fyl, fzl
349 chuckv 1388 ! real(kind = dp), parameter :: st = sqrt(3.0_dp)
350     real(kind = dp), parameter :: st = 1.732050807568877
351 gezelter 1174 integer :: atid1, atid2, id1, id2
352     logical :: shiftedPot, shiftedFrc
353 gezelter 1386
354 gezelter 1174 if (atid2.eq.MnM_Map%interactions(interaction_id)%metal_atid) then
355     ! rotate the inter-particle separation into the two different
356     ! body-fixed coordinate systems:
357 gezelter 1386
358     x = A1(1)*d(1) + A1(2)*d(2) + A1(3)*d(3)
359     y = A1(4)*d(1) + A1(5)*d(2) + A1(6)*d(3)
360     z = A1(7)*d(1) + A1(8)*d(2) + A1(9)*d(3)
361 gezelter 1174 else
362     ! negative sign because this is the vector from j to i:
363    
364 gezelter 1386 x = -(A2(1)*d(1) + A2(2)*d(2) + A2(3)*d(3))
365     y = -(A2(4)*d(1) + A2(5)*d(2) + A2(6)*d(3))
366     z = -(A2(7)*d(1) + A2(8)*d(2) + A2(9)*d(3))
367 gezelter 1174 endif
368 gezelter 1386
369 gezelter 1174 D0 = MnM_Map%interactions(interaction_id)%D0
370     R0 = MnM_Map%interactions(interaction_id)%r0
371 chuckv 1229 beta0 = MnM_Map%interactions(interaction_id)%beta0
372 gezelter 1238 ca1 = MnM_Map%interactions(interaction_id)%ca1
373     cb1 = MnM_Map%interactions(interaction_id)%cb1
374 chuckv 1175
375 gezelter 1174 shiftedPot = MnM_Map%interactions(interaction_id)%shiftedPot
376     shiftedFrc = MnM_Map%interactions(interaction_id)%shiftedFrc
377    
378     expt0 = -beta0*(rij - R0)
379     expfnc0 = exp(expt0)
380     expfnc02 = expfnc0*expfnc0
381 chuckv 1175
382 gezelter 1174 !!$ if (shiftedPot .or. shiftedFrc) then
383     !!$ exptC0 = -beta0*(rcut - R0)
384     !!$ expfncC0 = exp(exptC0)
385     !!$ expfncC02 = expfncC0*expfncC0
386     !!$ exptCH = -betaH*(rcut - R0)
387     !!$ expfncCH = exp(exptCH)
388     !!$ expfncCH2 = expfncCH*expfncCH
389     !!$ endif
390    
391 chuckv 1231 drdx = x / rij
392     drdy = y / rij
393     drdz = z / rij
394    
395 gezelter 1174 x2 = x*x
396     y2 = y*y
397     z2 = z*z
398 chuckv 1175 r3 = r2*rij
399 chuckv 1231 r4 = r2*r2
400 chuckv 1176
401 chuckv 1231 Vmorse = D0 * (expfnc02 - 2.0_dp * expfnc0)
402 chuckv 1176
403 gezelter 1238 ! angular modulation of morse part of potential to approximate
404     ! the squares of the two HOMO lone pair orbitals in water:
405 chuckv 1245 !********************** old form*************************
406 gezelter 1238 ! s = 1 / (4 pi)
407 gezelter 1386 ! ta1 = (s - pz)^2 = (1 - sqrt(3)*cos(theta))^2 / (4 pi)
408 gezelter 1238 ! b1 = px^2 = 3 * (sin(theta)*cos(phi))^2 / (4 pi)
409 chuckv 1245 !********************** old form*************************
410 gezelter 1238 ! we'll leave out the 4 pi for now
411 chuckv 1245
412     ! new functional form just using the p orbitals.
413     ! Vmorse(r)*[a*p_x + b p_z + (1-a-b)]
414     ! which is
415     ! Vmorse(r)*[a sin^2(theta) cos^2(phi) + b cos(theta) + (1-a-b)]
416     ! Vmorse(r)*[a*x2/r2 + b*z/r + (1-a-b)]
417 gezelter 1238
418 chuckv 1245
419    
420 gezelter 1238 s = 1.0_dp
421 gezelter 1386 ! ta1 = (1.0_dp - st * z / rij )**2
422 chuckv 1245 ! b1 = 3.0_dp * x2 / r2
423 gezelter 1238
424 gezelter 1386 ! Vang = s + ca1 * ta1 + cb1 * b1
425 chuckv 1245
426     Vang = ca1 * x2/r2 + cb1 * z/rij + (0.8_dp-ca1/3.0_dp)
427    
428 gezelter 1286 pot_temp = vdwMult * Vmorse*Vang
429 chuckv 1228
430 gezelter 1174 vpair = vpair + pot_temp
431 gezelter 1386 pot = pot + pot_temp*sw
432 chuckv 1175
433 chuckv 1229 dVmorsedr = 2.0_dp*D0*beta0*(expfnc0 - expfnc02)
434 chuckv 1231
435 chuckv 1229 dVmorsedx = dVmorsedr * drdx
436     dVmorsedy = dVmorsedr * drdy
437     dVmorsedz = dVmorsedr * drdz
438 gezelter 1238
439 chuckv 1245 !da1dx = 2.0_dp * st * x * z / r3 - 6.0_dp * x * z2 / r4
440     !da1dy = 2.0_dp * st * y * z / r3 - 6.0_dp * y * z2 / r4
441     !da1dz = 2.0_dp * st * (x2 + y2) * (st * z - rij ) / r4
442 chuckv 1231
443 chuckv 1245 !db1dx = 6.0_dp * x * (1.0_dp - x2 / r2) / r2
444     !db1dy = -6.0_dp * x2 * y / r4
445     !db1dz = -6.0_dp * x2 * z / r4
446 gezelter 1238
447 chuckv 1245 !dVangdx = ca1 * da1dx + cb1 * db1dx
448     !dVangdy = ca1 * da1dy + cb1 * db1dy
449     !dVangdz = ca1 * da1dz + cb1 * db1dz
450 chuckv 1228
451 chuckv 1245 dVangdx = -2.0*ca1*x2*x/r4 + 2.0*ca1*x/r2 - cb1*x*z/r3
452     dVangdy = -2.0*ca1*x2*y/r4 - cb1*z*y/r3
453     dVangdz = -2.0*ca1*x2*z/r4 + cb1/rij - cb1*z2 /r3
454    
455 chuckv 1231 ! chain rule to put these back on x, y, z
456 chuckv 1229 dvdx = Vang * dVmorsedx + Vmorse * dVangdx
457     dvdy = Vang * dVmorsedy + Vmorse * dVangdy
458     dvdz = Vang * dVmorsedz + Vmorse * dVangdz
459 gezelter 1174
460 chuckv 1231 ! Torques for Vang using method of Price:
461     ! S. L. Price, A. J. Stone, and M. Alderton, Mol. Phys. 52, 987 (1984).
462 gezelter 1238
463 chuckv 1245 !da1dux = 6.0_dp * y * z / r2 - 2.0_dp * st * y / rij
464     !da1duy = -6.0_dp * x * z / r2 + 2.0_dp * st * x / rij
465     !da1duz = 0.0_dp
466 gezelter 1238
467 chuckv 1245 !db1dux = 0.0_dp
468     !db1duy = 6.0_dp * x * z / r2
469     !db1duz = -6.0_dp * y * x / r2
470 gezelter 1238
471 chuckv 1245 !dVangdux = ca1 * da1dux + cb1 * db1dux
472     !dVangduy = ca1 * da1duy + cb1 * db1duy
473     !dVangduz = ca1 * da1duz + cb1 * db1duz
474 chuckv 1231
475 chuckv 1245 dVangdux = cb1*y/rij
476     dVangduy = 2.0*ca1*x*z/r2 - cb1*x/rij
477     dVangduz = -2.0*ca1*y*x/r2
478    
479 chuckv 1231 ! do the torques first since they are easy:
480     ! remember that these are still in the body fixed axes
481    
482 gezelter 1286 tx = vdwMult * Vmorse * dVangdux * sw
483     ty = vdwMult * Vmorse * dVangduy * sw
484     tz = vdwMult * Vmorse * dVangduz * sw
485 gezelter 1174
486     ! go back to lab frame using transpose of rotation matrix:
487    
488     if (atid2.eq.MnM_Map%interactions(interaction_id)%metal_atid) then
489 gezelter 1386 t1(1) = t1(1) + a1(1)*tx + a1(4)*ty + a1(7)*tz
490     t1(2) = t1(2) + a1(2)*tx + a1(5)*ty + a1(8)*tz
491     t1(3) = t1(3) + a1(3)*tx + a1(6)*ty + a1(9)*tz
492 gezelter 1174 else
493 gezelter 1386 t2(1) = t2(1) + a2(1)*tx + a2(4)*ty + a2(7)*tz
494     t2(2) = t2(2) + a2(2)*tx + a2(5)*ty + a2(8)*tz
495     t2(3) = t2(3) + a2(3)*tx + a2(6)*ty + a2(9)*tz
496 gezelter 1174 endif
497 gezelter 1386
498 chuckv 1231 ! Now, on to the forces (still in body frame of water)
499 gezelter 1174
500 gezelter 1286 fx = vdwMult * dvdx * sw
501     fy = vdwMult * dvdy * sw
502     fz = vdwMult * dvdz * sw
503 gezelter 1174
504     ! rotate the terms back into the lab frame:
505    
506     if (atid2.eq.MnM_Map%interactions(interaction_id)%metal_atid) then
507 gezelter 1386 fxl = a1(1)*fx + a1(4)*fy + a1(7)*fz
508     fyl = a1(2)*fx + a1(5)*fy + a1(8)*fz
509     fzl = a1(3)*fx + a1(6)*fy + a1(9)*fz
510 gezelter 1174 else
511 gezelter 1386 ! negative sign because this is the vector from j to i:
512     fxl = -(a2(1)*fx + a2(4)*fy + a2(7)*fz)
513     fyl = -(a2(2)*fx + a2(5)*fy + a2(8)*fz)
514     fzl = -(a2(3)*fx + a2(6)*fy + a2(9)*fz)
515 gezelter 1174 endif
516    
517 gezelter 1386 f1(1) = f1(1) + fxl
518     f1(2) = f1(2) + fyl
519     f1(3) = f1(3) + fzl
520 gezelter 1174
521     return
522 chuckv 1173 end subroutine calc_mnm_maw
523    
524    
525 chuckv 1168 subroutine setMnMDefaultCutoff(thisRcut, shiftedPot, shiftedFrc)
526     real(kind=dp), intent(in) :: thisRcut
527     logical, intent(in) :: shiftedPot
528     logical, intent(in) :: shiftedFrc
529     integer i, nInteractions
530     defaultCutoff = thisRcut
531     defaultShiftPot = shiftedPot
532     defaultShiftFrc = shiftedFrc
533    
534 xsun 1178 if (associated(MnM_Map)) then
535     if(MnM_Map%interactionCount /= 0) then
536     nInteractions = MnM_Map%interactionCount
537 chuckv 1168
538 xsun 1178 do i = 1, nInteractions
539     MnM_Map%interactions(i)%shiftedPot = shiftedPot
540     MnM_Map%interactions(i)%shiftedFrc = shiftedFrc
541     MnM_Map%interactions(i)%rCut = thisRcut
542     MnM_Map%interactions(i)%rCutWasSet = .true.
543     enddo
544     end if
545     end if
546 chuckv 1168
547     end subroutine setMnMDefaultCutoff
548    
549     subroutine copyAllData(v1, v2)
550     type(MnMinteractionMap), pointer :: v1
551     type(MnMinteractionMap), pointer :: v2
552     integer :: i, j
553    
554     do i = 1, v1%interactionCount
555     v2%interactions(i) = v1%interactions(i)
556     enddo
557    
558     v2%interactionCount = v1%interactionCount
559     return
560     end subroutine copyAllData
561    
562     subroutine addInteraction(myInteraction)
563     type(MNMtype) :: myInteraction
564     type(MnMinteraction) :: nt
565     integer :: id
566 chuckv 1175
567 chuckv 1168 nt%interaction_type = myInteraction%MNMInteractionType
568 chuckv 1175 nt%metal_atid = &
569     getFirstMatchingElement(atypes, "c_ident", myInteraction%metal_atid)
570     nt%nonmetal_atid = &
571     getFirstMatchingElement(atypes, "c_ident", myInteraction%nonmetal_atid)
572 gezelter 1284
573 chuckv 1168 select case (nt%interaction_type)
574     case (MNM_LENNARDJONES)
575     nt%sigma = myInteraction%sigma
576     nt%epsilon = myInteraction%epsilon
577     case(MNM_REPULSIVEMORSE, MNM_SHIFTEDMORSE)
578     nt%R0 = myInteraction%R0
579     nt%D0 = myInteraction%D0
580     nt%beta0 = myInteraction%beta0
581     case(MNM_MAW)
582     nt%R0 = myInteraction%R0
583     nt%D0 = myInteraction%D0
584     nt%beta0 = myInteraction%beta0
585 gezelter 1238 nt%ca1 = myInteraction%ca1
586     nt%cb1 = myInteraction%cb1
587 chuckv 1168 case default
588 chuckv 1173 call handleError("MNM", "Unknown Interaction type")
589 chuckv 1168 end select
590    
591     if (.not. associated(MnM_Map)) then
592     call ensureCapacityHelper(MnM_Map, 1)
593     else
594     call ensureCapacityHelper(MnM_Map, MnM_Map%interactionCount + 1)
595     end if
596    
597     MnM_Map%interactionCount = MnM_Map%interactionCount + 1
598     id = MnM_Map%interactionCount
599     MnM_Map%interactions(id) = nt
600     end subroutine addInteraction
601    
602     subroutine ensureCapacityHelper(this, minCapacity)
603     type(MnMinteractionMap), pointer :: this, that
604     integer, intent(in) :: minCapacity
605     integer :: oldCapacity
606     integer :: newCapacity
607     logical :: resizeFlag
608    
609     resizeFlag = .false.
610    
611     ! first time: allocate a new vector with default size
612    
613     if (.not. associated(this)) then
614     this => MnMinitialize(minCapacity, 0)
615     endif
616    
617     oldCapacity = size(this%interactions)
618    
619     if (minCapacity > oldCapacity) then
620     if (this%capacityIncrement .gt. 0) then
621     newCapacity = oldCapacity + this%capacityIncrement
622     else
623     newCapacity = oldCapacity * 2
624     endif
625     if (newCapacity .lt. minCapacity) then
626     newCapacity = minCapacity
627     endif
628     resizeFlag = .true.
629     else
630     newCapacity = oldCapacity
631     endif
632    
633     if (resizeFlag) then
634     that => MnMinitialize(newCapacity, this%capacityIncrement)
635     call copyAllData(this, that)
636     this => MnMdestroy(this)
637     this => that
638     endif
639     end subroutine ensureCapacityHelper
640    
641     function MnMinitialize(cap, capinc) result(this)
642     integer, intent(in) :: cap, capinc
643     integer :: error
644     type(MnMinteractionMap), pointer :: this
645    
646     nullify(this)
647    
648     if (cap < 0) then
649     write(*,*) 'Bogus Capacity:', cap
650     return
651     endif
652     allocate(this,stat=error)
653     if ( error /= 0 ) then
654     write(*,*) 'Could not allocate MnMinteractionMap!'
655     return
656     end if
657    
658     this%initialCapacity = cap
659     this%capacityIncrement = capinc
660    
661     allocate(this%interactions(this%initialCapacity), stat=error)
662     if(error /= 0) write(*,*) 'Could not allocate MnMinteraction!'
663    
664     end function MnMinitialize
665    
666 chuckv 1175 subroutine createInteractionLookup(this)
667     type (MnMInteractionMap),pointer :: this
668 chuckv 1168 integer :: biggestAtid, i, metal_atid, nonmetal_atid, error
669    
670     biggestAtid=-1
671     do i = 1, this%interactionCount
672     metal_atid = this%interactions(i)%metal_atid
673     nonmetal_atid = this%interactions(i)%nonmetal_atid
674    
675     if (metal_atid .gt. biggestAtid) biggestAtid = metal_atid
676     if (nonmetal_atid .gt. biggestAtid) biggestAtid = nonmetal_atid
677     enddo
678 chuckv 1175
679 chuckv 1168 allocate(MnMinteractionLookup(biggestAtid,biggestAtid), stat=error)
680     if (error /= 0) write(*,*) 'Could not allocate MnMinteractionLookup'
681    
682     do i = 1, this%interactionCount
683     metal_atid = this%interactions(i)%metal_atid
684     nonmetal_atid = this%interactions(i)%nonmetal_atid
685    
686     MnMinteractionLookup(metal_atid, nonmetal_atid) = i
687     MnMinteractionLookup(nonmetal_atid, metal_atid) = i
688     enddo
689     end subroutine createInteractionLookup
690    
691     function MnMdestroy(this) result(null_this)
692     logical :: done
693     type(MnMinteractionMap), pointer :: this
694     type(MnMinteractionMap), pointer :: null_this
695    
696     if (.not. associated(this)) then
697     null_this => null()
698     return
699     end if
700    
701     !! Walk down the list and deallocate each of the map's components
702     if(associated(this%interactions)) then
703     deallocate(this%interactions)
704     this%interactions=>null()
705     endif
706     deallocate(this)
707     this => null()
708     null_this => null()
709     end function MnMdestroy
710    
711     subroutine deleteInteractions()
712     MnM_Map => MnMdestroy(MnM_Map)
713     return
714     end subroutine deleteInteractions
715    
716 chuckv 1173 subroutine getLJfunc(r, myPot, myDeriv)
717    
718     real(kind=dp), intent(in) :: r
719     real(kind=dp), intent(inout) :: myPot, myDeriv
720     real(kind=dp) :: ri, ri2, ri6, ri7, ri12, ri13
721     real(kind=dp) :: a, b, c, d, dx
722     integer :: j
723    
724     ri = 1.0_DP / r
725     ri2 = ri*ri
726     ri6 = ri2*ri2*ri2
727     ri7 = ri6*ri
728     ri12 = ri6*ri6
729     ri13 = ri12*ri
730    
731     myPot = 4.0_DP * (ri12 - ri6)
732     myDeriv = 24.0_DP * (ri7 - 2.0_DP * ri13)
733    
734     return
735     end subroutine getLJfunc
736    
737     subroutine getSoftFunc(r, myPot, myDeriv)
738    
739     real(kind=dp), intent(in) :: r
740     real(kind=dp), intent(inout) :: myPot, myDeriv
741     real(kind=dp) :: ri, ri2, ri6, ri7
742     real(kind=dp) :: a, b, c, d, dx
743     integer :: j
744    
745     ri = 1.0_DP / r
746     ri2 = ri*ri
747     ri6 = ri2*ri2*ri2
748     ri7 = ri6*ri
749     myPot = 4.0_DP * (ri6)
750     myDeriv = - 24.0_DP * ri7
751    
752     return
753     end subroutine getSoftFunc
754 chuckv 1168 end module MetalNonMetal

Properties

Name Value
svn:keywords Author Id Revision Date