7 |
|
!! Corresponds to the force field defined in ssd_FF.cpp |
8 |
|
!! @author Charles F. Vardeman II |
9 |
|
!! @author Matthew Meineke |
10 |
< |
!! @version $Id: calc_sticky_pair.F90,v 1.1 2003-03-12 14:29:15 gezelter Exp $, $Date: 2003-03-12 14:29:15 $, $Name: not supported by cvs2svn $, $Revision: 1.1 $ |
10 |
> |
!! @author Christopher Fennel |
11 |
> |
!! @author J. Daniel Gezelter |
12 |
> |
!! @version $Id: calc_sticky_pair.F90,v 1.5 2003-03-12 19:31:55 gezelter Exp $, $Date: 2003-03-12 19:31:55 $, $Name: not supported by cvs2svn $, $Revision: 1.5 $ |
13 |
|
|
14 |
+ |
module sticky_pair |
15 |
|
|
13 |
– |
|
14 |
– |
module ssd_ff |
16 |
|
use simulation |
17 |
|
use definitions |
18 |
< |
use generic_atypes |
18 |
> |
use forceGlobals |
19 |
|
#ifdef IS_MPI |
20 |
|
use mpiSimulation |
21 |
|
#endif |
22 |
+ |
|
23 |
|
implicit none |
24 |
+ |
|
25 |
|
PRIVATE |
26 |
|
|
27 |
< |
!! Number of lj_atypes in lj_atype_list |
28 |
< |
integer, save :: n_atypes = 0 |
27 |
> |
logical, save :: sticky_initialized = .false. |
28 |
> |
real( kind = dp ), save :: SSD_w0 |
29 |
> |
real( kind = dp ), save :: SSD_v0 |
30 |
> |
real( kind = dp ), save :: SSD_rl |
31 |
> |
real( kind = dp ), save :: SSD_ru |
32 |
> |
real( kind = dp ), save :: SSD_rup |
33 |
|
|
34 |
< |
!! Global list of lj atypes in simulation |
35 |
< |
type (ssd_atype), pointer :: ListHead => null() |
36 |
< |
type (ssd_atype), pointer :: ListTail => null() |
34 |
> |
public :: check_sticky_FF |
35 |
> |
public :: set_sticky_params |
36 |
> |
public :: do_sticky_pair |
37 |
|
|
31 |
– |
|
32 |
– |
!! LJ mixing array |
33 |
– |
type (ssd_atype), dimension(:,:), pointer :: Mixed => null() |
34 |
– |
|
35 |
– |
|
36 |
– |
!! Neighbor list and commom arrays |
37 |
– |
!! This should eventally get moved to a neighbor list type |
38 |
– |
integer, allocatable, dimension(:) :: point |
39 |
– |
integer, allocatable, dimension(:) :: list |
40 |
– |
integer, parameter :: listMultiplier = 80 |
41 |
– |
integer :: nListAllocs = 0 |
42 |
– |
integer, parameter :: maxListAllocs = 5 |
43 |
– |
|
44 |
– |
logical, save :: firstTime = .True. |
45 |
– |
|
46 |
– |
!! Atype identity pointer lists |
47 |
– |
#ifdef IS_MPI |
48 |
– |
!! Row lj_atype pointer list |
49 |
– |
type (ssd_identPtrList), dimension(:), pointer :: identPtrListRow => null() |
50 |
– |
!! Column lj_atype pointer list |
51 |
– |
type (ssd_identPtrList), dimension(:), pointer :: identPtrListColumn => null() |
52 |
– |
#else |
53 |
– |
type( ssd_identPtrList ), dimension(:), pointer :: identPtrList => null() |
54 |
– |
#endif |
55 |
– |
|
56 |
– |
|
57 |
– |
!! Logical has lj force field module been initialized? |
58 |
– |
logical, save :: isFFinit = .false. |
59 |
– |
|
60 |
– |
|
61 |
– |
!! Public methods and data |
62 |
– |
public :: new_ssd_atype |
63 |
– |
public :: do_SSD_ff |
64 |
– |
public :: getSSDForce |
65 |
– |
public :: init_ssdFF |
66 |
– |
|
67 |
– |
|
68 |
– |
|
69 |
– |
|
38 |
|
contains |
39 |
|
|
40 |
< |
!! Adds a new lj_atype to the list. |
41 |
< |
subroutine new_ssd_atype(ident,mass,epsilon,sigma,dipoleMoment,& |
42 |
< |
hasDipole,v0,w0,status) |
43 |
< |
real( kind = dp ), intent(in) :: mass |
44 |
< |
real( kind = dp ), intent(in) :: epsilon |
45 |
< |
real( kind = dp ), intent(in) :: sigma |
78 |
< |
real( kind = dp ), intent(in) :: dipoleMoment |
79 |
< |
logical :: hasDipole |
80 |
< |
real( kind = dp ), intent(in) :: w0 |
81 |
< |
real( kind = dp ), intent(in) :: v0 |
82 |
< |
integer, intent(in) :: ident |
83 |
< |
integer, intent(out) :: status |
40 |
> |
subroutine check_sticky_FF(status) |
41 |
> |
integer :: status |
42 |
> |
status = -1 |
43 |
> |
if (sticky_initialized) status = 0 |
44 |
> |
return |
45 |
> |
end subroutine check_sticky_FF |
46 |
|
|
47 |
< |
type (ssd_atype), pointer :: newSSD_atype |
48 |
< |
integer :: alloc_error |
49 |
< |
integer :: atype_counter = 0 |
50 |
< |
integer :: alloc_size |
51 |
< |
integer :: err_stat |
52 |
< |
status = 0 |
53 |
< |
|
54 |
< |
|
55 |
< |
|
56 |
< |
! allocate a new atype |
95 |
< |
allocate(newSSD_atype,stat=alloc_error) |
96 |
< |
if (alloc_error /= 0 ) then |
97 |
< |
status = -1 |
98 |
< |
return |
99 |
< |
end if |
100 |
< |
|
101 |
< |
! assign our new lj_atype information |
102 |
< |
newSSD_atype%lj_parms%mass = mass |
103 |
< |
newSSD_atype%lj_parms%epsilon = epsilon |
104 |
< |
newSSD_atype%lj_parms%sigma = sigma |
105 |
< |
newSSD_atype%lj_parms%sigma2 = sigma * sigma |
106 |
< |
newSSD_atype%lj_parms%sigma6 = newLJ_atype%sigma2 * newLJ_atype%sigma2 & |
107 |
< |
* newLJ_atype%sigma2 |
108 |
< |
newSSD_atype%dipoleMoment = dipoleMoment |
109 |
< |
newSSD_atype&hasDipole = hasDipole |
110 |
< |
newSSD_atype%w0 = w0 |
111 |
< |
newSSD_atype%v0 = v0 |
112 |
< |
! assume that this atype will be successfully added |
113 |
< |
newSSD_atype%atype_ident = ident |
114 |
< |
newSSD_atype%atype_number = n_SSD_atypes + 1 |
115 |
< |
|
116 |
< |
call add_atype(newSSD_atype,ListHead,ListTail,err_stat) |
117 |
< |
if (err_stat /= 0 ) then |
118 |
< |
status = -1 |
119 |
< |
return |
120 |
< |
endif |
121 |
< |
|
122 |
< |
n_ssd_atypes = n_ssd_atypes + 1 |
123 |
< |
|
124 |
< |
|
125 |
< |
end subroutine new_ssd_atype |
126 |
< |
|
127 |
< |
|
128 |
< |
subroutine init_ssdFF(nComponents,ident, status) |
129 |
< |
!! Number of components in ident array |
130 |
< |
integer, intent(inout) :: nComponents |
131 |
< |
!! Array of identities nComponents long corresponding to |
132 |
< |
!! ljatype ident. |
133 |
< |
integer, dimension(nComponents),intent(inout) :: ident |
134 |
< |
!! Result status, success = 0, error = -1 |
135 |
< |
integer, intent(out) :: Status |
136 |
< |
|
137 |
< |
integer :: alloc_stat |
138 |
< |
|
139 |
< |
integer :: thisStat |
140 |
< |
integer :: i |
141 |
< |
|
142 |
< |
integer :: myNode |
143 |
< |
#ifdef IS_MPI |
144 |
< |
integer, allocatable, dimension(:) :: identRow |
145 |
< |
integer, allocatable, dimension(:) :: identCol |
146 |
< |
integer :: nrow |
147 |
< |
integer :: ncol |
148 |
< |
#endif |
149 |
< |
status = 0 |
47 |
> |
subroutine set_sticky_params(sticky_w0, sticky_v0) |
48 |
> |
real( kind = dp ), intent(in) :: sticky_w0, sticky_v0 |
49 |
> |
|
50 |
> |
! we could pass all 5 parameters if we felt like it... |
51 |
> |
|
52 |
> |
SSD_w0 = sticky_w0 |
53 |
> |
SSD_v0 = sticky_v0 |
54 |
> |
SSD_rl = 2.75_DP |
55 |
> |
SSD_ru = 3.35_DP |
56 |
> |
SSD_rup = 4.0_DP |
57 |
|
|
58 |
+ |
sticky_initialized = .true. |
59 |
+ |
return |
60 |
+ |
end subroutine set_sticky_params |
61 |
|
|
62 |
+ |
subroutine do_sticky_pair(atom1, atom2, d, rij, r2, A, pot, f, t, & |
63 |
+ |
do_pot, do_stress) |
64 |
|
|
65 |
+ |
!! This routine does only the sticky portion of the SSD potential |
66 |
+ |
!! [Chandra and Ichiye, J. Chem. Phys. 111, 2701 (1999)]. |
67 |
+ |
!! The Lennard-Jones and dipolar interaction must be handled separately. |
68 |
+ |
|
69 |
+ |
!! We assume that the rotation matrices have already been calculated |
70 |
+ |
!! and placed in the A array. |
71 |
+ |
|
72 |
+ |
!! i and j are pointers to the two SSD atoms |
73 |
|
|
74 |
< |
!! if were're not in MPI, we just update ljatypePtrList |
75 |
< |
#ifndef IS_MPI |
76 |
< |
call create_IdentPtrlst(ident,ListHead,identPtrList,thisStat) |
77 |
< |
if ( thisStat /= 0 ) then |
78 |
< |
status = -1 |
79 |
< |
return |
80 |
< |
endif |
74 |
> |
integer, intent(in) :: atom1, atom2 |
75 |
> |
real (kind=dp), intent(inout) :: rij, r2 |
76 |
> |
real (kind=dp), dimension(3), intent(in) :: d |
77 |
> |
real (kind=dp) :: pot |
78 |
> |
real (kind=dp), dimension(9,getNlocal()) :: A |
79 |
> |
real (kind=dp), dimension(3,getNlocal()) :: f |
80 |
> |
real (kind=dp), dimension(3,getNlocal()) :: t |
81 |
> |
logical, intent(in) :: do_pot, do_stress |
82 |
|
|
83 |
< |
!! Allocate pointer lists |
84 |
< |
allocate(point(nComponents),stat=alloc_stat) |
85 |
< |
if (alloc_stat /=0) then |
86 |
< |
status = -1 |
83 |
> |
real (kind=dp) :: xi, yi, zi, xj, yj, zj, xi2, yi2, zi2, xj2, yj2, zj2 |
84 |
> |
real (kind=dp) :: r3, r5, r6, s, sp, dsdr, dspdr |
85 |
> |
real (kind=dp) :: wi, wj, w, wip, wjp, wp |
86 |
> |
real (kind=dp) :: dwidx, dwidy, dwidz, dwjdx, dwjdy, dwjdz |
87 |
> |
real (kind=dp) :: dwipdx, dwipdy, dwipdz, dwjpdx, dwjpdy, dwjpdz |
88 |
> |
real (kind=dp) :: dwidux, dwiduy, dwiduz, dwjdux, dwjduy, dwjduz |
89 |
> |
real (kind=dp) :: dwipdux, dwipduy, dwipduz, dwjpdux, dwjpduy, dwjpduz |
90 |
> |
real (kind=dp) :: zif, zis, zjf, zjs, uglyi, uglyj |
91 |
> |
real (kind=dp) :: drdx, drdy, drdz |
92 |
> |
real (kind=dp) :: txi, tyi, tzi, txj, tyj, tzj |
93 |
> |
real (kind=dp) :: fxii, fyii, fzii, fxjj, fyjj, fzjj |
94 |
> |
real (kind=dp) :: fxij, fyij, fzij, fxji, fyji, fzji |
95 |
> |
real (kind=dp) :: fxradial, fyradial, fzradial |
96 |
> |
|
97 |
> |
if (.not.sticky_initialized) then |
98 |
> |
write(*,*) 'Sticky forces not initialized!' |
99 |
|
return |
100 |
|
endif |
101 |
|
|
102 |
< |
allocate(list(nComponents*listMultiplier),stat=alloc_stat) |
103 |
< |
if (alloc_stat /=0) then |
171 |
< |
status = -1 |
172 |
< |
return |
173 |
< |
endif |
102 |
> |
r3 = r2*rij |
103 |
> |
r5 = r3*r2 |
104 |
|
|
105 |
< |
! if were're in MPI, we also have to worry about row and col lists |
105 |
> |
drdx = d(1) / rij |
106 |
> |
drdy = d(2) / rij |
107 |
> |
drdz = d(3) / rij |
108 |
> |
|
109 |
> |
#ifdef IS_MPI |
110 |
> |
! rotate the inter-particle separation into the two different |
111 |
> |
! body-fixed coordinate systems: |
112 |
> |
|
113 |
> |
xi = A_row(1,atom1)*d(1) + A_row(2,atom1)*d(2) + A_row(3,atom1)*d(3) |
114 |
> |
yi = A_row(4,atom1)*d(1) + A_row(5,atom1)*d(2) + A_row(6,atom1)*d(3) |
115 |
> |
zi = A_row(7,atom1)*d(1) + A_row(8,atom1)*d(2) + A_row(9,atom1)*d(3) |
116 |
> |
|
117 |
> |
! negative sign because this is the vector from j to i: |
118 |
> |
|
119 |
> |
xj = -(A_Col(1,atom2)*d(1) + A_Col(2,atom2)*d(2) + A_Col(3,atom2)*d(3)) |
120 |
> |
yj = -(A_Col(4,atom2)*d(1) + A_Col(5,atom2)*d(2) + A_Col(6,atom2)*d(3)) |
121 |
> |
zj = -(A_Col(7,atom2)*d(1) + A_Col(8,atom2)*d(2) + A_Col(9,atom2)*d(3)) |
122 |
|
#else |
123 |
< |
|
124 |
< |
! We can only set up forces if mpiSimulation has been setup. |
179 |
< |
if (.not. isMPISimSet()) then |
180 |
< |
write(default_error,*) "MPI is not set" |
181 |
< |
status = -1 |
182 |
< |
return |
183 |
< |
endif |
184 |
< |
nrow = getNrow(plan_row) |
185 |
< |
ncol = getNcol(plan_col) |
186 |
< |
mynode = getMyNode() |
187 |
< |
!! Allocate temperary arrays to hold gather information |
188 |
< |
allocate(identRow(nrow),stat=alloc_stat) |
189 |
< |
if (alloc_stat /= 0 ) then |
190 |
< |
status = -1 |
191 |
< |
return |
192 |
< |
endif |
193 |
< |
|
194 |
< |
allocate(identCol(ncol),stat=alloc_stat) |
195 |
< |
if (alloc_stat /= 0 ) then |
196 |
< |
status = -1 |
197 |
< |
return |
198 |
< |
endif |
199 |
< |
|
200 |
< |
!! Gather idents into row and column idents |
201 |
< |
|
202 |
< |
call gather(ident,identRow,plan_row) |
203 |
< |
call gather(ident,identCol,plan_col) |
123 |
> |
! rotate the inter-particle separation into the two different |
124 |
> |
! body-fixed coordinate systems: |
125 |
|
|
126 |
< |
|
127 |
< |
!! Create row and col pointer lists |
128 |
< |
|
129 |
< |
call create_IdentPtrlst(identRow,ListHead,identPtrListRow,thisStat) |
130 |
< |
if (thisStat /= 0 ) then |
131 |
< |
status = -1 |
132 |
< |
return |
133 |
< |
endif |
134 |
< |
|
214 |
< |
call create_IdentPtrlst(identCol,ListHead,identPtrListColumn,thisStat) |
215 |
< |
if (thisStat /= 0 ) then |
216 |
< |
status = -1 |
217 |
< |
return |
218 |
< |
endif |
219 |
< |
|
220 |
< |
!! free temporary ident arrays |
221 |
< |
if (allocated(identCol)) then |
222 |
< |
deallocate(identCol) |
223 |
< |
end if |
224 |
< |
if (allocated(identCol)) then |
225 |
< |
deallocate(identRow) |
226 |
< |
endif |
227 |
< |
|
228 |
< |
!! Allocate neighbor lists for mpi simulations. |
229 |
< |
if (.not. allocated(point)) then |
230 |
< |
allocate(point(nrow),stat=alloc_stat) |
231 |
< |
if (alloc_stat /=0) then |
232 |
< |
status = -1 |
233 |
< |
return |
234 |
< |
endif |
235 |
< |
|
236 |
< |
allocate(list(ncol*listMultiplier),stat=alloc_stat) |
237 |
< |
if (alloc_stat /=0) then |
238 |
< |
status = -1 |
239 |
< |
return |
240 |
< |
endif |
241 |
< |
else |
242 |
< |
deallocate(list) |
243 |
< |
deallocate(point) |
244 |
< |
allocate(point(nrow),stat=alloc_stat) |
245 |
< |
if (alloc_stat /=0) then |
246 |
< |
status = -1 |
247 |
< |
return |
248 |
< |
endif |
249 |
< |
|
250 |
< |
allocate(list(ncol*listMultiplier),stat=alloc_stat) |
251 |
< |
if (alloc_stat /=0) then |
252 |
< |
status = -1 |
253 |
< |
return |
254 |
< |
endif |
255 |
< |
endif |
256 |
< |
|
126 |
> |
xi = a(1,atom1)*d(1) + a(2,atom1)*d(2) + a(3,atom1)*d(3) |
127 |
> |
yi = a(4,atom1)*d(1) + a(5,atom1)*d(2) + a(6,atom1)*d(3) |
128 |
> |
zi = a(7,atom1)*d(1) + a(8,atom1)*d(2) + a(9,atom1)*d(3) |
129 |
> |
|
130 |
> |
! negative sign because this is the vector from j to i: |
131 |
> |
|
132 |
> |
xj = -(a(1,atom2)*d(1) + a(2,atom2)*d(2) + a(3,atom2)*d(3)) |
133 |
> |
yj = -(a(4,atom2)*d(1) + a(5,atom2)*d(2) + a(6,atom2)*d(3)) |
134 |
> |
zj = -(a(7,atom2)*d(1) + a(8,atom2)*d(2) + a(9,atom2)*d(3)) |
135 |
|
#endif |
136 |
|
|
137 |
< |
call createMixingList(thisStat) |
138 |
< |
if (thisStat /= 0) then |
139 |
< |
status = -1 |
262 |
< |
return |
263 |
< |
endif |
264 |
< |
isFFinit = .true. |
265 |
< |
|
266 |
< |
|
267 |
< |
end subroutine init_ssdFF |
268 |
< |
|
269 |
< |
|
270 |
< |
|
271 |
< |
|
272 |
< |
|
273 |
< |
|
274 |
< |
subroutine createMixingList(status) |
275 |
< |
integer :: listSize |
276 |
< |
integer :: status |
277 |
< |
integer :: i |
278 |
< |
integer :: j |
279 |
< |
|
280 |
< |
integer :: outerCounter = 0 |
281 |
< |
integer :: innerCounter = 0 |
282 |
< |
type (lj_atype), pointer :: tmpPtrOuter => null() |
283 |
< |
type (lj_atype), pointer :: tmpPtrInner => null() |
284 |
< |
status = 0 |
285 |
< |
|
286 |
< |
listSize = getListLen(ListHead) |
287 |
< |
if (listSize == 0) then |
288 |
< |
status = -1 |
289 |
< |
return |
290 |
< |
end if |
291 |
< |
|
292 |
< |
|
293 |
< |
if (.not. associated(Mixed)) then |
294 |
< |
allocate(Mixed(listSize,listSize)) |
295 |
< |
else |
296 |
< |
status = -1 |
297 |
< |
return |
298 |
< |
end if |
299 |
< |
|
137 |
> |
xi2 = xi*xi |
138 |
> |
yi2 = yi*yi |
139 |
> |
zi2 = zi*zi |
140 |
|
|
141 |
< |
|
142 |
< |
tmpPtrOuter => ListHead |
143 |
< |
tmpPtrInner => tmpPtrOuter%next |
304 |
< |
do while (associated(tmpPtrOuter)) |
305 |
< |
outerCounter = outerCounter + 1 |
306 |
< |
! do self mixing rule |
307 |
< |
Mixed(outerCounter,outerCounter)%sigma = tmpPtrOuter%sigma |
308 |
< |
|
309 |
< |
Mixed(outerCounter,outerCounter)%sigma2 = Mixed(outerCounter,outerCounter)%sigma & |
310 |
< |
* Mixed(outerCounter,outerCounter)%sigma |
311 |
< |
|
312 |
< |
Mixed(outerCounter,outerCounter)%sigma6 = Mixed(outerCounter,outerCounter)%sigma2 & |
313 |
< |
* Mixed(outerCounter,outerCounter)%sigma2 & |
314 |
< |
* Mixed(outerCounter,outerCounter)%sigma2 |
315 |
< |
|
316 |
< |
Mixed(outerCounter,outerCounter)%epsilon = tmpPtrOuter%epsilon |
317 |
< |
|
318 |
< |
innerCounter = outerCounter + 1 |
319 |
< |
do while (associated(tmpPtrInner)) |
320 |
< |
|
321 |
< |
Mixed(outerCounter,innerCounter)%sigma = & |
322 |
< |
calcLJMix("sigma",tmpPtrOuter%sigma, & |
323 |
< |
tmpPtrInner%sigma) |
324 |
< |
|
325 |
< |
Mixed(outerCounter,innerCounter)%sigma2 = & |
326 |
< |
Mixed(outerCounter,innerCounter)%sigma & |
327 |
< |
* Mixed(outerCounter,innerCounter)%sigma |
328 |
< |
|
329 |
< |
Mixed(outerCounter,innerCounter)%sigma6 = & |
330 |
< |
Mixed(outerCounter,innerCounter)%sigma2 & |
331 |
< |
* Mixed(outerCounter,innerCounter)%sigma2 & |
332 |
< |
* Mixed(outerCounter,innerCounter)%sigma2 |
333 |
< |
|
334 |
< |
Mixed(outerCounter,innerCounter)%epsilon = & |
335 |
< |
calcLJMix("epsilon",tmpPtrOuter%epsilon, & |
336 |
< |
tmpPtrInner%epsilon) |
337 |
< |
Mixed(innerCounter,outerCounter)%sigma = Mixed(outerCounter,innerCounter)%sigma |
338 |
< |
Mixed(innerCounter,outerCounter)%sigma2 = Mixed(outerCounter,innerCounter)%sigma2 |
339 |
< |
Mixed(innerCounter,outerCounter)%sigma6 = Mixed(outerCounter,innerCounter)%sigma6 |
340 |
< |
Mixed(innerCounter,outerCounter)%epsilon = Mixed(outerCounter,innerCounter)%epsilon |
341 |
< |
|
342 |
< |
|
343 |
< |
tmpPtrInner => tmpPtrInner%next |
344 |
< |
innerCounter = innerCounter + 1 |
345 |
< |
end do |
346 |
< |
! advance pointers |
347 |
< |
tmpPtrOuter => tmpPtrOuter%next |
348 |
< |
if (associated(tmpPtrOuter)) then |
349 |
< |
tmpPtrInner => tmpPtrOuter%next |
350 |
< |
endif |
351 |
< |
|
352 |
< |
end do |
353 |
< |
|
354 |
< |
end subroutine createMixingList |
355 |
< |
|
356 |
< |
|
357 |
< |
|
358 |
< |
|
359 |
< |
|
360 |
< |
|
361 |
< |
|
362 |
< |
|
363 |
< |
!! FORCE routine Calculates Lennard Jones forces. |
364 |
< |
!-------------------------------------------------------------> |
365 |
< |
subroutine do_ssd_ff(q,f,t,u,A,potE,do_pot) |
366 |
< |
!! Position array provided by C, dimensioned by getNlocal |
367 |
< |
real ( kind = dp ), dimension(3,getNlocal()) :: q |
368 |
< |
!! Force array given to C, dimensioned by getNlocal |
369 |
< |
real ( kind = dp ), dimension(3,getNlocal()) :: f |
370 |
< |
!! Torsion array given to C, dimensioned by getNlocal |
371 |
< |
real ( kind = dp ), dimension(3,getNlocal()) :: t |
372 |
< |
!! Dipole unit vectors given to C, dimensioned by getNlocal |
373 |
< |
real ( kind = dp ), dimension(3,getNlocal()) :: u |
374 |
< |
|
375 |
< |
|
376 |
< |
|
377 |
< |
!! rotational array -- 9 element matrix |
378 |
< |
!! 1 - Axx |
379 |
< |
!! 2 - Axy |
380 |
< |
!! 3 - Axz |
381 |
< |
!! 4 - Ayx |
382 |
< |
!! 5 - Ayy |
383 |
< |
!! 6 - Ayz |
384 |
< |
!! 7 - Azx |
385 |
< |
!! 8 - Azy |
386 |
< |
!! 9 - Azz |
387 |
< |
real( kind = dp ), dimension(9,getNlocal()) :: A |
388 |
< |
|
389 |
< |
real ( kind = dp ) :: potE |
390 |
< |
logical ( kind = 2) :: do_pot |
141 |
> |
xj2 = xj*xj |
142 |
> |
yj2 = yj*yj |
143 |
> |
zj2 = zj*zj |
144 |
|
|
145 |
< |
type(ssd_atype), pointer :: Atype_i |
146 |
< |
type(ssd_atype), pointer :: Atype_j |
145 |
> |
call calc_sw_fnc(rij, s, sp, dsdr, dspdr) |
146 |
> |
|
147 |
> |
wi = 2.0d0*(xi2-yi2)*zi / r3 |
148 |
> |
wj = 2.0d0*(xj2-yj2)*zj / r3 |
149 |
> |
w = wi+wj |
150 |
> |
|
151 |
> |
zif = zi/rij - 0.6d0 |
152 |
> |
zis = zi/rij + 0.8d0 |
153 |
> |
|
154 |
> |
zjf = zj/rij - 0.6d0 |
155 |
> |
zjs = zj/rij + 0.8d0 |
156 |
> |
|
157 |
> |
wip = zif*zif*zis*zis - SSD_w0 |
158 |
> |
wjp = zjf*zjf*zjs*zjs - SSD_w0 |
159 |
> |
wp = wip + wjp |
160 |
|
|
161 |
|
|
162 |
< |
!! Force from SSD due to (ndim,i-j(1) and j-i(2)) |
163 |
< |
real( kind = dp ), dimension(3,2) :: fl_ij_ji = 0.0_dp |
164 |
< |
!! Torsion from SSD due to (ndim,i-j(1) and j-i(2)) |
165 |
< |
real( kind = dp ), dimension(3,2) :: tl_ij_ji = 0.0_dp |
400 |
< |
|
401 |
< |
#ifdef IS_MPI |
402 |
< |
real( kind = DP ), dimension(3,getNcol(plan_col)) :: efr = 0.0_dp |
403 |
< |
real( kind = DP ) :: pot_local = 0.0_dp |
162 |
> |
if (do_pot) then |
163 |
> |
#ifdef IS_MPI |
164 |
> |
pot_row(atom1) = pot_row(atom1) + 0.25d0*SSD_v0*(s*w + sp*wp) |
165 |
> |
pot_col(atom2) = pot_col(atom2) + 0.25d0*SSD_v0*(s*w + sp*wp) |
166 |
|
#else |
167 |
< |
real( kind = DP ), dimension(3,getNlocal()) :: efr = 0.0_dp |
168 |
< |
#endif |
167 |
> |
pot = pot + 0.5d0*SSD_v0*(s*w + sp*wp) |
168 |
> |
#endif |
169 |
> |
endif |
170 |
> |
|
171 |
> |
dwidx = 4.0d0*xi*zi/r3 - 6.0d0*xi*zi*(xi2-yi2)/r5 |
172 |
> |
dwidy = - 4.0d0*yi*zi/r3 - 6.0d0*yi*zi*(xi2-yi2)/r5 |
173 |
> |
dwidz = 2.0d0*(xi2-yi2)/r3 - 6.0d0*zi2*(xi2-yi2)/r5 |
174 |
> |
|
175 |
> |
dwjdx = 4.0d0*xj*zj/r3 - 6.0d0*xj*zj*(xj2-yj2)/r5 |
176 |
> |
dwjdy = - 4.0d0*yj*zj/r3 - 6.0d0*yj*zj*(xj2-yj2)/r5 |
177 |
> |
dwjdz = 2.0d0*(xj2-yj2)/r3 - 6.0d0*zj2*(xj2-yj2)/r5 |
178 |
> |
|
179 |
> |
uglyi = zif*zif*zis + zif*zis*zis |
180 |
> |
uglyj = zjf*zjf*zjs + zjf*zjs*zjs |
181 |
> |
|
182 |
> |
dwipdx = -2.0d0*xi*zi*uglyi/r3 |
183 |
> |
dwipdy = -2.0d0*yi*zi*uglyi/r3 |
184 |
> |
dwipdz = 2.0d0*(1.0d0/rij - zi2/r3)*uglyi |
185 |
> |
|
186 |
> |
dwjpdx = -2.0d0*xj*zj*uglyj/r3 |
187 |
> |
dwjpdy = -2.0d0*yj*zj*uglyj/r3 |
188 |
> |
dwjpdz = 2.0d0*(1.0d0/rij - zj2/r3)*uglyj |
189 |
> |
|
190 |
> |
dwidux = 4.0d0*(yi*zi2 + 0.5d0*yi*(xi2-yi2))/r3 |
191 |
> |
dwiduy = 4.0d0*(xi*zi2 - 0.5d0*xi*(xi2-yi2))/r3 |
192 |
> |
dwiduz = - 8.0d0*xi*yi*zi/r3 |
193 |
> |
|
194 |
> |
dwjdux = 4.0d0*(yj*zj2 + 0.5d0*yj*(xj2-yj2))/r3 |
195 |
> |
dwjduy = 4.0d0*(xj*zj2 - 0.5d0*xj*(xj2-yj2))/r3 |
196 |
> |
dwjduz = - 8.0d0*xj*yj*zj/r3 |
197 |
> |
|
198 |
> |
dwipdux = 2.0d0*yi*uglyi/rij |
199 |
> |
dwipduy = -2.0d0*xi*uglyi/rij |
200 |
> |
dwipduz = 0.0d0 |
201 |
> |
|
202 |
> |
dwjpdux = 2.0d0*yj*uglyj/rij |
203 |
> |
dwjpduy = -2.0d0*xj*uglyj/rij |
204 |
> |
dwjpduz = 0.0d0 |
205 |
> |
|
206 |
> |
! do the torques first since they are easy: |
207 |
> |
! remember that these are still in the body fixed axes |
208 |
> |
|
209 |
> |
txi = 0.5d0*SSD_v0*(s*dwidux + sp*dwipdux) |
210 |
> |
tyi = 0.5d0*SSD_v0*(s*dwiduy + sp*dwipduy) |
211 |
> |
tzi = 0.5d0*SSD_v0*(s*dwiduz + sp*dwipduz) |
212 |
> |
|
213 |
> |
txj = 0.5d0*SSD_v0*(s*dwjdux + sp*dwjpdux) |
214 |
> |
tyj = 0.5d0*SSD_v0*(s*dwjduy + sp*dwjpduy) |
215 |
> |
tzj = 0.5d0*SSD_v0*(s*dwjduz + sp*dwjpduz) |
216 |
> |
|
217 |
> |
! go back to lab frame using transpose of rotation matrix: |
218 |
|
|
408 |
– |
!! Local arrays needed for MPI |
219 |
|
#ifdef IS_MPI |
220 |
< |
!! Position arrays |
221 |
< |
real(kind = dp), dimension(3,getNrow(plan_row)) :: qRow = 0.0_dp |
222 |
< |
real(kind = dp), dimension(3,getNcol(plan_col)) :: qCol = 0.0_dp |
223 |
< |
|
224 |
< |
!! Rotational Arrays -- note 9 element matrix same layout as A |
225 |
< |
real(kind = dp), dimension(9,getNrow(plan_row)) :: ARow = 0.0_dp |
416 |
< |
real(kind = dp), dimension(9,getNcol(plan_col)) :: ACol = 0.0_dp |
417 |
< |
|
418 |
< |
!! Force Arrays |
419 |
< |
real(kind = dp), dimension(3,getNrow(plan_row)) :: fRow = 0.0_dp |
420 |
< |
real(kind = dp), dimension(3,getNcol(plan_col)) :: fCol = 0.0_dp |
421 |
< |
real(kind = dp), dimension(3,getNlocal()) :: fMPITemp = 0.0_dp |
422 |
< |
!! Torsion arrays |
423 |
< |
real(kind = dp), dimension(3,getNrow(plan_row)) :: tRow = 0.0_dp |
424 |
< |
real(kind = dp), dimension(3,getNcol(plan_col)) :: tCol = 0.0_dp |
425 |
< |
real(kind = dp), dimension(3,getNlocal()) :: tMPITemp = 0.0_dp |
426 |
< |
|
427 |
< |
|
428 |
< |
|
429 |
< |
real(kind = dp), dimension(getNrow(plan_row)) :: eRow = 0.0_dp |
430 |
< |
real(kind = dp), dimension(getNcol(plan_col)) :: eCol = 0.0_dp |
220 |
> |
t_Row(1,atom1) = t_Row(1,atom1) + a_Row(1,atom1)*txi + & |
221 |
> |
a_Row(4,atom1)*tyi + a_Row(7,atom1)*tzi |
222 |
> |
t_Row(2,atom1) = t_Row(2,atom1) + a_Row(2,atom1)*txi + & |
223 |
> |
a_Row(5,atom1)*tyi + a_Row(8,atom1)*tzi |
224 |
> |
t_Row(3,atom1) = t_Row(3,atom1) + a_Row(3,atom1)*txi + & |
225 |
> |
a_Row(6,atom1)*tyi + a_Row(9,atom1)*tzi |
226 |
|
|
227 |
< |
real(kind = dp), dimension(getNlocal()) :: eTemp = 0.0_dp |
228 |
< |
#endif |
229 |
< |
|
230 |
< |
real( kind = DP ) :: pe = 0.0_dp |
231 |
< |
logical :: update_nlist |
227 |
> |
t_Col(1,atom2) = t_Col(1,atom2) + a_Col(1,atom2)*txj + & |
228 |
> |
a_Col(4,atom2)*tyj + a_Col(7,atom2)*tzj |
229 |
> |
t_Col(2,atom2) = t_Col(2,atom2) + a_Col(2,atom2)*txj + & |
230 |
> |
a_Col(5,atom2)*tyj + a_Col(8,atom2)*tzj |
231 |
> |
t_Col(3,atom2) = t_Col(3,atom2) + a_Col(3,atom2)*txj + & |
232 |
> |
a_Col(6,atom2)*tyj + a_Col(9,atom2)*tzj |
233 |
> |
#else |
234 |
> |
t(1,atom1) = t(1,atom1) + a(1,atom1)*txi + a(4,atom1)*tyi + a(7,atom1)*tzi |
235 |
> |
t(2,atom1) = t(2,atom1) + a(2,atom1)*txi + a(5,atom1)*tyi + a(8,atom1)*tzi |
236 |
> |
t(3,atom1) = t(3,atom1) + a(3,atom1)*txi + a(6,atom1)*tyi + a(9,atom1)*tzi |
237 |
> |
|
238 |
> |
t(1,atom2) = t(1,atom2) + a(1,atom2)*txj + a(4,atom2)*tyj + a(7,atom2)*tzj |
239 |
> |
t(2,atom2) = t(2,atom2) + a(2,atom2)*txj + a(5,atom2)*tyj + a(8,atom2)*tzj |
240 |
> |
t(3,atom2) = t(3,atom2) + a(3,atom2)*txj + a(6,atom2)*tyj + a(9,atom2)*tzj |
241 |
> |
#endif |
242 |
> |
! Now, on to the forces: |
243 |
> |
|
244 |
> |
! first rotate the i terms back into the lab frame: |
245 |
|
|
246 |
+ |
#ifdef IS_MPI |
247 |
+ |
fxii = a_Row(1,atom1)*(s*dwidx+sp*dwipdx) + & |
248 |
+ |
a_Row(4,atom1)*(s*dwidy+sp*dwipdy) + & |
249 |
+ |
a_Row(7,atom1)*(s*dwidz+sp*dwipdz) |
250 |
+ |
fyii = a_Row(2,atom1)*(s*dwidx+sp*dwipdx) + & |
251 |
+ |
a_Row(5,atom1)*(s*dwidy+sp*dwipdy) + & |
252 |
+ |
a_Row(8,atom1)*(s*dwidz+sp*dwipdz) |
253 |
+ |
fzii = a_Row(3,atom1)*(s*dwidx+sp*dwipdx) + & |
254 |
+ |
a_Row(6,atom1)*(s*dwidy+sp*dwipdy) + & |
255 |
+ |
a_Row(9,atom1)*(s*dwidz+sp*dwipdz) |
256 |
|
|
257 |
< |
integer :: i, j, jbeg, jend, jnab, idim, jdim, idim2, jdim2, dim, dim2 |
258 |
< |
integer :: nlist |
259 |
< |
integer :: j_start |
260 |
< |
integer :: tag_i,tag_j |
261 |
< |
real( kind = DP ) :: r, pot, ftmp, dudr, d2, drdx1, kt1, kt2, kt3, ktmp |
262 |
< |
real( kind = DP ) :: rxi, ryi, rzi, rxij, ryij, rzij, rijsq |
263 |
< |
real( kind = DP ) :: rlistsq, rcutsq,rlist,rcut |
257 |
> |
fxjj = a_Col(1,atom2)*(s*dwjdx+sp*dwjpdx) + & |
258 |
> |
a_Col(4,atom2)*(s*dwjdy+sp*dwjpdy) + & |
259 |
> |
a_Col(7,atom2)*(s*dwjdz+sp*dwjpdz) |
260 |
> |
fyjj = a_Col(2,atom2)*(s*dwjdx+sp*dwjpdx) + & |
261 |
> |
a_Col(5,atom2)*(s*dwjdy+sp*dwjpdy) + & |
262 |
> |
a_Col(8,atom2)*(s*dwjdz+sp*dwjpdz) |
263 |
> |
fzjj = a_Col(3,atom2)*(s*dwjdx+sp*dwjpdx)+ & |
264 |
> |
a_Col(6,atom2)*(s*dwjdy+sp*dwjpdy) + & |
265 |
> |
a_Col(9,atom2)*(s*dwjdz+sp*dwjpdz) |
266 |
> |
#else |
267 |
> |
fxii = a(1,atom1)*(s*dwidx+sp*dwipdx) + & |
268 |
> |
a(4,atom1)*(s*dwidy+sp*dwipdy) + & |
269 |
> |
a(7,atom1)*(s*dwidz+sp*dwipdz) |
270 |
> |
fyii = a(2,atom1)*(s*dwidx+sp*dwipdx) + & |
271 |
> |
a(5,atom1)*(s*dwidy+sp*dwipdy) + & |
272 |
> |
a(8,atom1)*(s*dwidz+sp*dwipdz) |
273 |
> |
fzii = a(3,atom1)*(s*dwidx+sp*dwipdx) + & |
274 |
> |
a(6,atom1)*(s*dwidy+sp*dwipdy) + & |
275 |
> |
a(9,atom1)*(s*dwidz+sp*dwipdz) |
276 |
|
|
277 |
< |
! a rig that need to be fixed. |
278 |
< |
#ifdef IS_MPI |
279 |
< |
logical :: newtons_thrd = .true. |
280 |
< |
real( kind = dp ) :: pe_local = 0.0_dp |
277 |
> |
fxjj = a(1,atom2)*(s*dwjdx+sp*dwjpdx) + & |
278 |
> |
a(4,atom2)*(s*dwjdy+sp*dwjpdy) + & |
279 |
> |
a(7,atom2)*(s*dwjdz+sp*dwjpdz) |
280 |
> |
fyjj = a(2,atom2)*(s*dwjdx+sp*dwjpdx) + & |
281 |
> |
a(5,atom2)*(s*dwjdy+sp*dwjpdy) + & |
282 |
> |
a(8,atom2)*(s*dwjdz+sp*dwjpdz) |
283 |
> |
fzjj = a(3,atom2)*(s*dwjdx+sp*dwjpdx)+ & |
284 |
> |
a(6,atom2)*(s*dwjdy+sp*dwjpdy) + & |
285 |
> |
a(9,atom2)*(s*dwjdz+sp*dwjpdz) |
286 |
|
#endif |
452 |
– |
integer :: nrow |
453 |
– |
integer :: ncol |
454 |
– |
integer :: nlocal |
455 |
– |
|
456 |
– |
|
457 |
– |
|
458 |
– |
|
459 |
– |
! Make sure we are properly initialized. |
460 |
– |
if (.not. isljFFInit) then |
461 |
– |
write(default_error,*) "ERROR: lj_FF has not been properly initialized" |
462 |
– |
return |
463 |
– |
endif |
464 |
– |
#ifdef IS_MPI |
465 |
– |
if (.not. isMPISimSet()) then |
466 |
– |
write(default_error,*) "ERROR: mpiSimulation has not been properly initialized" |
467 |
– |
return |
468 |
– |
endif |
469 |
– |
#endif |
470 |
– |
|
471 |
– |
!! initialize local variables |
472 |
– |
nlocal = getNlocal() |
473 |
– |
call getRcut(rcut,rcut2=rcutsq) |
474 |
– |
call getRlist(rlist,rlistsq) |
475 |
– |
|
476 |
– |
#ifndef IS_MPI |
477 |
– |
nrow = nlocal - 1 |
478 |
– |
ncol = nlocal |
479 |
– |
#else |
480 |
– |
nrow = getNrow(plan_row) |
481 |
– |
ncol = getNcol(plan_col) |
482 |
– |
j_start = 1 |
483 |
– |
#endif |
484 |
– |
|
485 |
– |
|
486 |
– |
!! See if we need to update neighbor lists |
487 |
– |
call check(q,update_nlist) |
488 |
– |
if (firstTime) then |
489 |
– |
update_nlist = .true. |
490 |
– |
firstTime = .false. |
491 |
– |
endif |
492 |
– |
|
493 |
– |
|
494 |
– |
!--------------WARNING........................... |
495 |
– |
! Zero variables, NOTE:::: Forces are zeroed in C |
496 |
– |
! Zeroing them here could delete previously computed |
497 |
– |
! Forces. |
498 |
– |
!------------------------------------------------ |
499 |
– |
#ifndef IS_MPI |
500 |
– |
! nloops = nloops + 1 |
501 |
– |
pe = 0.0E0_DP |
502 |
– |
|
503 |
– |
#else |
504 |
– |
fRow = 0.0E0_DP |
505 |
– |
fCol = 0.0E0_DP |
287 |
|
|
288 |
< |
pe_local = 0.0E0_DP |
288 |
> |
fxij = -fxii |
289 |
> |
fyij = -fyii |
290 |
> |
fzij = -fzii |
291 |
> |
|
292 |
> |
fxji = -fxjj |
293 |
> |
fyji = -fyjj |
294 |
> |
fzji = -fzjj |
295 |
> |
|
296 |
> |
! now assemble these with the radial-only terms: |
297 |
|
|
298 |
< |
eRow = 0.0E0_DP |
299 |
< |
eCol = 0.0E0_DP |
300 |
< |
eTemp = 0.0E0_DP |
512 |
< |
#endif |
513 |
< |
efr = 0.0E0_DP |
514 |
< |
|
515 |
< |
|
516 |
< |
#ifdef IS_MPI |
517 |
< |
! communicate local MPI position arrays into row and column arrays. |
518 |
< |
call gather(q,qRow,plan_row3d) |
519 |
< |
call gather(q,qCol,plan_col3d) |
520 |
< |
! communicate local MPI Rotational Array into row and column arrays. |
521 |
< |
call gather(A,ARow,plan_row_Rotation) |
522 |
< |
call gather(A,ACol,plan_col_Rotation) |
523 |
< |
#endif |
524 |
< |
|
525 |
< |
|
526 |
< |
if (update_nlist) then |
527 |
< |
|
528 |
< |
! save current configuration, contruct neighbor list, |
529 |
< |
! and calculate forces |
530 |
< |
call save_nlist(q) |
298 |
> |
fxradial = 0.5d0*SSD_v0*(dsdr*drdx*w + dspdr*drdx*wp + fxii + fxji) |
299 |
> |
fyradial = 0.5d0*SSD_v0*(dsdr*drdy*w + dspdr*drdy*wp + fyii + fyji) |
300 |
> |
fzradial = 0.5d0*SSD_v0*(dsdr*drdz*w + dspdr*drdz*wp + fzii + fzji) |
301 |
|
|
532 |
– |
nlist = 0 |
533 |
– |
|
534 |
– |
|
535 |
– |
|
536 |
– |
do i = 1, nrow |
537 |
– |
point(i) = nlist + 1 |
302 |
|
#ifdef IS_MPI |
303 |
< |
Atype_i => identPtrListRow(i)%this |
304 |
< |
tag_i = tagRow(i) |
305 |
< |
rxi = qRow(1,i) |
306 |
< |
ryi = qRow(2,i) |
307 |
< |
rzi = qRow(3,i) |
303 |
> |
f_Row(1,atom1) = f_Row(1,atom1) + fxradial |
304 |
> |
f_Row(2,atom1) = f_Row(2,atom1) + fyradial |
305 |
> |
f_Row(3,atom1) = f_Row(3,atom1) + fzradial |
306 |
> |
|
307 |
> |
f_Col(1,atom2) = f_Col(1,atom2) + 0.5d0*SSD_v0*(-dsdr*drdx*w - & |
308 |
> |
dspdr*drdx*wp + fxjj + fxij) |
309 |
> |
f_Col(2,atom2) = f_Col(2,atom2) + 0.5d0*SSD_v0*(-dsdr*drdy*w - & |
310 |
> |
dspdr*drdy*wp + fyjj + fyij) |
311 |
> |
f_Col(3,atom2) = f_Col(3,atom2) + 0.5d0*SSD_v0*(-dsdr*drdz*w - & |
312 |
> |
dspdr*drdz*wp + fzjj + fzij) |
313 |
|
#else |
314 |
< |
Atype_i => identPtrList(i)%this |
315 |
< |
j_start = i + 1 |
316 |
< |
rxi = q(1,i) |
317 |
< |
ryi = q(2,i) |
318 |
< |
rzi = q(3,i) |
314 |
> |
f(1,atom1) = f(1,atom1) + fxradial |
315 |
> |
f(2,atom1) = f(2,atom1) + fyradial |
316 |
> |
f(3,atom1) = f(3,atom1) + fzradial |
317 |
> |
|
318 |
> |
f(1,atom2) = f(1,atom2) + 0.5d0*SSD_v0*(-dsdr*drdx*w - dspdr*drdx*wp + & |
319 |
> |
fxjj + fxij) |
320 |
> |
f(2,atom2) = f(2,atom2) + 0.5d0*SSD_v0*(-dsdr*drdy*w - dspdr*drdy*wp + & |
321 |
> |
fyjj + fyij) |
322 |
> |
f(3,atom2) = f(3,atom2) + 0.5d0*SSD_v0*(-dsdr*drdz*w - dspdr*drdz*wp + & |
323 |
> |
fzjj + fzij) |
324 |
|
#endif |
325 |
+ |
|
326 |
+ |
if (do_stress) then |
327 |
+ |
tau_Temp(1) = tau_Temp(1) + fxradial * d(1) |
328 |
+ |
tau_Temp(2) = tau_Temp(2) + fxradial * d(2) |
329 |
+ |
tau_Temp(3) = tau_Temp(3) + fxradial * d(3) |
330 |
+ |
tau_Temp(4) = tau_Temp(4) + fyradial * d(1) |
331 |
+ |
tau_Temp(5) = tau_Temp(5) + fyradial * d(2) |
332 |
+ |
tau_Temp(6) = tau_Temp(6) + fyradial * d(3) |
333 |
+ |
tau_Temp(7) = tau_Temp(7) + fzradial * d(1) |
334 |
+ |
tau_Temp(8) = tau_Temp(8) + fzradial * d(2) |
335 |
+ |
tau_Temp(9) = tau_Temp(9) + fzradial * d(3) |
336 |
+ |
virial_Temp = virial_Temp + (tau_Temp(1) + tau_Temp(5) + tau_Temp(9)) |
337 |
+ |
endif |
338 |
+ |
|
339 |
+ |
end subroutine do_sticky_pair |
340 |
|
|
341 |
< |
inner: do j = j_start, ncol |
342 |
< |
#ifdef IS_MPI |
554 |
< |
! Assign identity pointers and tags |
555 |
< |
Atype_j => identPtrListColumn(j)%this |
556 |
< |
tag_j = tagColumn(j) |
557 |
< |
if (newtons_thrd) then |
558 |
< |
if (tag_i <= tag_j) then |
559 |
< |
if (mod(tag_i + tag_j,2) == 0) cycle inner |
560 |
< |
else |
561 |
< |
if (mod(tag_i + tag_j,2) == 1) cycle inner |
562 |
< |
endif |
563 |
< |
endif |
564 |
< |
|
565 |
< |
rxij = wrap(rxi - qCol(1,j), 1) |
566 |
< |
ryij = wrap(ryi - qCol(2,j), 2) |
567 |
< |
rzij = wrap(rzi - qCol(3,j), 3) |
568 |
< |
#else |
569 |
< |
Atype_j => identPtrList(j)%this |
570 |
< |
rxij = wrap(rxi - q(1,j), 1) |
571 |
< |
ryij = wrap(ryi - q(2,j), 2) |
572 |
< |
rzij = wrap(rzi - q(3,j), 3) |
573 |
< |
|
574 |
< |
#endif |
575 |
< |
rijsq = rxij*rxij + ryij*ryij + rzij*rzij |
576 |
< |
|
577 |
< |
#ifdef IS_MPI |
578 |
< |
if (rijsq <= rlistsq .AND. & |
579 |
< |
tag_j /= tag_i) then |
580 |
< |
#else |
341 |
> |
!! calculates the switching functions and their derivatives for a given |
342 |
> |
subroutine calc_sw_fnc(r, s, sp, dsdr, dspdr) |
343 |
|
|
344 |
< |
if (rijsq < rlistsq) then |
345 |
< |
#endif |
584 |
< |
|
585 |
< |
nlist = nlist + 1 |
586 |
< |
if (nlist > size(list)) then |
587 |
< |
!! "Change how nlist size is done" |
588 |
< |
write(DEFAULT_ERROR,*) "ERROR: nlist > list size" |
589 |
< |
endif |
590 |
< |
list(nlist) = j |
344 |
> |
real (kind=dp), intent(in) :: r |
345 |
> |
real (kind=dp), intent(inout) :: s, sp, dsdr, dspdr |
346 |
|
|
347 |
+ |
! distances must be in angstroms |
348 |
|
|
349 |
< |
if (rijsq < rcutsq) then |
350 |
< |
|
351 |
< |
r = dsqrt(rijsq) |
352 |
< |
|
353 |
< |
call getLJPot(r,pot,dudr,Atype_i,type_j) |
349 |
> |
if (r.lt.SSD_rl) then |
350 |
> |
s = 1.0d0 |
351 |
> |
sp = 1.0d0 |
352 |
> |
dsdr = 0.0d0 |
353 |
> |
dspdr = 0.0d0 |
354 |
> |
elseif (r.gt.SSD_rup) then |
355 |
> |
s = 0.0d0 |
356 |
> |
sp = 0.0d0 |
357 |
> |
dsdr = 0.0d0 |
358 |
> |
dspdr = 0.0d0 |
359 |
> |
else |
360 |
> |
sp = ((SSD_rup + 2.0d0*r - 3.0d0*SSD_rl) * (SSD_rup-r)**2) / & |
361 |
> |
((SSD_rup - SSD_rl)**3) |
362 |
> |
dspdr = 6.0d0*(r-SSD_rup)*(r-SSD_rl)/((SSD_rup - SSD_rl)**3) |
363 |
|
|
364 |
< |
#ifdef IS_MPI |
365 |
< |
eRow(i) = eRow(i) + pot*0.5 |
366 |
< |
eCol(i) = eCol(i) + pot*0.5 |
602 |
< |
#else |
603 |
< |
pe = pe + pot |
604 |
< |
#endif |
605 |
< |
|
606 |
< |
efr(1,j) = -rxij |
607 |
< |
efr(2,j) = -ryij |
608 |
< |
efr(3,j) = -rzij |
609 |
< |
|
610 |
< |
do dim = 1, 3 |
611 |
< |
|
612 |
< |
|
613 |
< |
drdx1 = efr(dim,j) / r |
614 |
< |
ftmp = dudr * drdx1 |
615 |
< |
|
616 |
< |
|
617 |
< |
#ifdef IS_MPI |
618 |
< |
fCol(dim,j) = fCol(dim,j) - ftmp |
619 |
< |
fRow(dim,i) = fRow(dim,i) + ftmp |
620 |
< |
#else |
621 |
< |
|
622 |
< |
f(dim,j) = f(dim,j) - ftmp |
623 |
< |
f(dim,i) = f(dim,i) + ftmp |
624 |
< |
|
625 |
< |
#endif |
626 |
< |
enddo |
627 |
< |
endif |
628 |
< |
endif |
629 |
< |
enddo inner |
630 |
< |
enddo |
631 |
< |
|
632 |
< |
#ifdef IS_MPI |
633 |
< |
point(nrow + 1) = nlist + 1 |
634 |
< |
#else |
635 |
< |
point(natoms) = nlist + 1 |
636 |
< |
#endif |
637 |
< |
|
364 |
> |
if (r.gt.SSD_ru) then |
365 |
> |
s = 0.0d0 |
366 |
> |
dsdr = 0.0d0 |
367 |
|
else |
368 |
< |
|
369 |
< |
! use the list to find the neighbors |
370 |
< |
do i = 1, nrow |
642 |
< |
JBEG = POINT(i) |
643 |
< |
JEND = POINT(i+1) - 1 |
644 |
< |
! check thiat molecule i has neighbors |
645 |
< |
if (jbeg .le. jend) then |
646 |
< |
#ifdef IS_MPI |
647 |
< |
Atype_i => identPtrListRow(i)%this |
648 |
< |
rxi = qRow(1,i) |
649 |
< |
ryi = qRow(2,i) |
650 |
< |
rzi = qRow(3,i) |
651 |
< |
#else |
652 |
< |
Atype_i => identPtrList(i)%this |
653 |
< |
rxi = q(1,i) |
654 |
< |
ryi = q(2,i) |
655 |
< |
rzi = q(3,i) |
656 |
< |
#endif |
657 |
< |
do jnab = jbeg, jend |
658 |
< |
j = list(jnab) |
659 |
< |
#ifdef IS_MPI |
660 |
< |
Atype_j = identPtrListColumn(j)%this |
661 |
< |
rxij = wrap(rxi - qCol(1,j), 1) |
662 |
< |
ryij = wrap(ryi - qCol(2,j), 2) |
663 |
< |
rzij = wrap(rzi - qCol(3,j), 3) |
664 |
< |
#else |
665 |
< |
Atype_j = identPtrList(j)%this |
666 |
< |
rxij = wrap(rxi - q(1,j), 1) |
667 |
< |
ryij = wrap(ryi - q(2,j), 2) |
668 |
< |
rzij = wrap(rzi - q(3,j), 3) |
669 |
< |
#endif |
670 |
< |
rijsq = rxij*rxij + ryij*ryij + rzij*rzij |
671 |
< |
|
672 |
< |
if (rijsq < rcutsq) then |
673 |
< |
|
674 |
< |
r = dsqrt(rijsq) |
675 |
< |
|
676 |
< |
call getSSDPot(r,pot,dudr,Atype_i,Atype_j) |
677 |
< |
#ifdef IS_MPI |
678 |
< |
eRow(i) = eRow(i) + pot*0.5 |
679 |
< |
eCol(i) = eCol(i) + pot*0.5 |
680 |
< |
#else |
681 |
< |
pe = pe + pot |
682 |
< |
#endif |
683 |
< |
|
684 |
< |
|
685 |
< |
efr(1,j) = -rxij |
686 |
< |
efr(2,j) = -ryij |
687 |
< |
efr(3,j) = -rzij |
688 |
< |
|
689 |
< |
do dim = 1, 3 |
690 |
< |
|
691 |
< |
drdx1 = efr(dim,j) / r |
692 |
< |
ftmp = dudr * drdx1 |
693 |
< |
#ifdef IS_MPI |
694 |
< |
fCol(dim,j) = fCol(dim,j) - ftmp |
695 |
< |
fRow(dim,i) = fRow(dim,i) + ftmp |
696 |
< |
#else |
697 |
< |
f(dim,j) = f(dim,j) - ftmp |
698 |
< |
f(dim,i) = f(dim,i) + ftmp |
699 |
< |
#endif |
700 |
< |
enddo |
701 |
< |
endif |
702 |
< |
enddo |
703 |
< |
endif |
704 |
< |
enddo |
705 |
< |
endif |
706 |
< |
|
707 |
< |
|
708 |
< |
|
709 |
< |
#ifdef IS_MPI |
710 |
< |
!!distribute forces |
711 |
< |
|
712 |
< |
call scatter(fRow,f,plan_row3d) |
713 |
< |
|
714 |
< |
call scatter(fCol,fMPITemp,plan_col3d) |
715 |
< |
|
716 |
< |
do i = 1,nlocal |
717 |
< |
f(1:3,i) = f(1:3,i) + fMPITemp(1:3,i) |
718 |
< |
end do |
719 |
< |
|
720 |
< |
|
721 |
< |
|
722 |
< |
if (do_pot) then |
723 |
< |
! scatter/gather pot_row into the members of my column |
724 |
< |
call scatter(eRow,eTemp,plan_row) |
725 |
< |
|
726 |
< |
! scatter/gather pot_local into all other procs |
727 |
< |
! add resultant to get total pot |
728 |
< |
do i = 1, nlocal |
729 |
< |
pe_local = pe_local + eTemp(i) |
730 |
< |
enddo |
731 |
< |
if (newtons_thrd) then |
732 |
< |
eTemp = 0.0E0_DP |
733 |
< |
call scatter(eCol,eTemp,plan_col) |
734 |
< |
do i = 1, nlocal |
735 |
< |
pe_local = pe_local + eTemp(i) |
736 |
< |
enddo |
368 |
> |
s = ((SSD_ru + 2.0d0*r - 3.0d0*SSD_rl) * (SSD_ru-r)**2) / & |
369 |
> |
((SSD_ru - SSD_rl)**3) |
370 |
> |
dsdr = 6.0d0*(r-SSD_ru)*(r-SSD_rl)/((SSD_ru - SSD_rl)**3) |
371 |
|
endif |
738 |
– |
pe = pe_local |
372 |
|
endif |
373 |
< |
|
374 |
< |
#endif |
375 |
< |
|
376 |
< |
potE = pe |
744 |
< |
|
745 |
< |
end subroutine do_ssd_ff |
746 |
< |
|
747 |
< |
|
748 |
< |
|
749 |
< |
!! This routine does only the sticky portion of the SSD potential |
750 |
< |
!! [Chandra and Ichiye, J. Chem. Phys. 111, 2701 (1999)]. |
751 |
< |
!! The Lennard-Jones and dipolar interaction must be handled separately. |
752 |
< |
|
753 |
< |
!! We assume that the rotation matrices have already been calculated |
754 |
< |
!! and placed in the A(9, max_mol) array. |
755 |
< |
|
756 |
< |
!! i and j are pointers to the two SSD molecules, while atom1 and |
757 |
< |
!! atom2 are the pointers to the location of the atoms in the force |
758 |
< |
!! and position arrays. These are both necessary since the rotation |
759 |
< |
!! matrix is a property of the molecule, while the force is acting on |
760 |
< |
!! the atom. The indexing of atoms and molecules is not necessarily |
761 |
< |
!! the same in simulations of mixtures. |
762 |
< |
|
763 |
< |
! subroutine getSSDSticky(natoms, i, j, atom1, atom2, dx, dy, dz, rij, pot, r2, & |
764 |
< |
! flx, fly, flz, tlx, tly, tlz, a) |
765 |
< |
subroutine getSSDSticky(r,r_ij,r__2,a,fl_ij,tl_ij,pot) |
766 |
< |
|
767 |
< |
!! Position vector between particle i and particle j |
768 |
< |
real( kind = dp ) :: r |
769 |
< |
!! Components of position vector between particle i and particle j |
770 |
< |
real( kind = dp), dimension(3) :: r_ij |
771 |
< |
!! Position vector squared |
772 |
< |
real( kind = dp ) :: r__2 |
773 |
< |
!! Rotation matrix |
774 |
< |
real( kind = dp ), dimension(:,:) :: a |
775 |
< |
|
776 |
< |
!! force |
777 |
< |
|
778 |
< |
|
779 |
< |
integer :: i, j, atom1, atom2, natoms |
780 |
< |
double precision dx, dy, dz, rij, pot, r2 |
781 |
< |
double precision, dimension(natoms) ::flx, fly, flz, tlx, tly, tlz |
782 |
< |
double precision, dimension(9,natoms):: a |
783 |
< |
|
784 |
< |
|
785 |
< |
double precision xi, yi, zi, xj, yj, zj, xi2, yi2, zi2, xj2, yj2, zj2 |
786 |
< |
double precision r3, r5, r6, s, sp, dsdr, dspdr |
787 |
< |
double precision wi, wj, w, wip, wjp, wp |
788 |
< |
double precision dwidx, dwidy, dwidz, dwjdx, dwjdy, dwjdz |
789 |
< |
double precision dwipdx, dwipdy, dwipdz, dwjpdx, dwjpdy, dwjpdz |
790 |
< |
double precision dwidux, dwiduy, dwiduz, dwjdux, dwjduy, dwjduz |
791 |
< |
double precision dwipdux, dwipduy, dwipduz, dwjpdux, dwjpduy, dwjpduz |
792 |
< |
double precision zif, zis, zjf, zjs, uglyi, uglyj |
793 |
< |
double precision drdx, drdy, drdz |
794 |
< |
double precision txi, tyi, tzi, txj, tyj, tzj |
795 |
< |
double precision fxii, fyii, fzii, fxjj, fyjj, fzjj |
796 |
< |
double precision fxij, fyij, fzij, fxji, fyji, fzji |
797 |
< |
|
798 |
< |
|
799 |
< |
! Use molecular positions, since the SSD model has only one atom, and the |
800 |
< |
! rotation matrix is for the molecule itself: |
801 |
< |
|
802 |
< |
r3 = r2*rij |
803 |
< |
r5 = r3*r2 |
804 |
< |
|
805 |
< |
drdx = dx / rij |
806 |
< |
drdy = dy / rij |
807 |
< |
drdz = dz / rij |
808 |
< |
|
809 |
< |
! rotate the inter-particle separation into the two different |
810 |
< |
! body-fixed coordinate systems: |
811 |
< |
|
812 |
< |
xi = a(1,i)*dx + a(2,i)*dy + a(3,i)*dz |
813 |
< |
yi = a(4,i)*dx + a(5,i)*dy + a(6,i)*dz |
814 |
< |
zi = a(7,i)*dx + a(8,i)*dy + a(9,i)*dz |
815 |
< |
|
816 |
< |
! negative sign because this is the vector from j to i: |
817 |
< |
|
818 |
< |
xj = -(a(1,j)*dx + a(2,j)*dy + a(3,j)*dz) |
819 |
< |
yj = -(a(4,j)*dx + a(5,j)*dy + a(6,j)*dz) |
820 |
< |
zj = -(a(7,j)*dx + a(8,j)*dy + a(9,j)*dz) |
821 |
< |
|
822 |
< |
xi2 = xi*xi |
823 |
< |
yi2 = yi*yi |
824 |
< |
zi2 = zi*zi |
825 |
< |
|
826 |
< |
xj2 = xj*xj |
827 |
< |
yj2 = yj*yj |
828 |
< |
zj2 = zj*zj |
829 |
< |
|
830 |
< |
call calc_sw_fnc(rij, s, sp, dsdr, dspdr) |
831 |
< |
|
832 |
< |
wi = 2.0d0*(xi2-yi2)*zi / r3 |
833 |
< |
wj = 2.0d0*(xj2-yj2)*zj / r3 |
834 |
< |
w = wi+wj |
835 |
< |
|
836 |
< |
zif = zi/rij - 0.6d0 |
837 |
< |
zis = zi/rij + 0.8d0 |
838 |
< |
|
839 |
< |
zjf = zj/rij - 0.6d0 |
840 |
< |
zjs = zj/rij + 0.8d0 |
841 |
< |
|
842 |
< |
wip = zif*zif*zis*zis - SSD_w0 |
843 |
< |
wjp = zjf*zjf*zjs*zjs - SSD_w0 |
844 |
< |
wp = wip + wjp |
845 |
< |
|
846 |
< |
pot = pot + 0.5d0*SSD_v0*(s*w + sp*wp) |
847 |
< |
|
848 |
< |
dwidx = 4.0d0*xi*zi/r3 - 6.0d0*xi*zi*(xi2-yi2)/r5 |
849 |
< |
dwidy = - 4.0d0*yi*zi/r3 - 6.0d0*yi*zi*(xi2-yi2)/r5 |
850 |
< |
dwidz = 2.0d0*(xi2-yi2)/r3 - 6.0d0*zi2*(xi2-yi2)/r5 |
851 |
< |
|
852 |
< |
dwjdx = 4.0d0*xj*zj/r3 - 6.0d0*xj*zj*(xj2-yj2)/r5 |
853 |
< |
dwjdy = - 4.0d0*yj*zj/r3 - 6.0d0*yj*zj*(xj2-yj2)/r5 |
854 |
< |
dwjdz = 2.0d0*(xj2-yj2)/r3 - 6.0d0*zj2*(xj2-yj2)/r5 |
855 |
< |
|
856 |
< |
uglyi = zif*zif*zis + zif*zis*zis |
857 |
< |
uglyj = zjf*zjf*zjs + zjf*zjs*zjs |
858 |
< |
|
859 |
< |
dwipdx = -2.0d0*xi*zi*uglyi/r3 |
860 |
< |
dwipdy = -2.0d0*yi*zi*uglyi/r3 |
861 |
< |
dwipdz = 2.0d0*(1.0d0/rij - zi2/r3)*uglyi |
862 |
< |
|
863 |
< |
dwjpdx = -2.0d0*xj*zj*uglyj/r3 |
864 |
< |
dwjpdy = -2.0d0*yj*zj*uglyj/r3 |
865 |
< |
dwjpdz = 2.0d0*(1.0d0/rij - zj2/r3)*uglyj |
866 |
< |
|
867 |
< |
dwidux = 4.0d0*(yi*zi2 + 0.5d0*yi*(xi2-yi2))/r3 |
868 |
< |
dwiduy = 4.0d0*(xi*zi2 - 0.5d0*xi*(xi2-yi2))/r3 |
869 |
< |
dwiduz = - 8.0d0*xi*yi*zi/r3 |
870 |
< |
|
871 |
< |
dwjdux = 4.0d0*(yj*zj2 + 0.5d0*yj*(xj2-yj2))/r3 |
872 |
< |
dwjduy = 4.0d0*(xj*zj2 - 0.5d0*xj*(xj2-yj2))/r3 |
873 |
< |
dwjduz = - 8.0d0*xj*yj*zj/r3 |
874 |
< |
|
875 |
< |
dwipdux = 2.0d0*yi*uglyi/rij |
876 |
< |
dwipduy = -2.0d0*xi*uglyi/rij |
877 |
< |
dwipduz = 0.0d0 |
878 |
< |
|
879 |
< |
dwjpdux = 2.0d0*yj*uglyj/rij |
880 |
< |
dwjpduy = -2.0d0*xj*uglyj/rij |
881 |
< |
dwjpduz = 0.0d0 |
882 |
< |
|
883 |
< |
! do the torques first since they are easy: |
884 |
< |
! remember that these are still in the body fixed axes |
885 |
< |
|
886 |
< |
txi = 0.5d0*SSD_v0*(s*dwidux + sp*dwipdux) |
887 |
< |
tyi = 0.5d0*SSD_v0*(s*dwiduy + sp*dwipduy) |
888 |
< |
tzi = 0.5d0*SSD_v0*(s*dwiduz + sp*dwipduz) |
889 |
< |
|
890 |
< |
txj = 0.5d0*SSD_v0*(s*dwjdux + sp*dwjpdux) |
891 |
< |
tyj = 0.5d0*SSD_v0*(s*dwjduy + sp*dwjpduy) |
892 |
< |
tzj = 0.5d0*SSD_v0*(s*dwjduz + sp*dwjpduz) |
893 |
< |
|
894 |
< |
! go back to lab frame using transpose of rotation matrix: |
895 |
< |
|
896 |
< |
tlx(atom1) = tlx(atom1) + a(1,i)*txi + a(4,i)*tyi + a(7,i)*tzi |
897 |
< |
tly(atom1) = tly(atom1) + a(2,i)*txi + a(5,i)*tyi + a(8,i)*tzi |
898 |
< |
tlz(atom1) = tlz(atom1) + a(3,i)*txi + a(6,i)*tyi + a(9,i)*tzi |
899 |
< |
|
900 |
< |
tlx(atom2) = tlx(atom2) + a(1,j)*txj + a(4,j)*tyj + a(7,j)*tzj |
901 |
< |
tly(atom2) = tly(atom2) + a(2,j)*txj + a(5,j)*tyj + a(8,j)*tzj |
902 |
< |
tlz(atom2) = tlz(atom2) + a(3,j)*txj + a(6,j)*tyj + a(9,j)*tzj |
903 |
< |
|
904 |
< |
! Now, on to the forces: |
905 |
< |
|
906 |
< |
! first rotate the i terms back into the lab frame: |
907 |
< |
|
908 |
< |
fxii = a(1,i)*(s*dwidx+sp*dwipdx) + & |
909 |
< |
a(4,i)*(s*dwidy+sp*dwipdy) + & |
910 |
< |
a(7,i)*(s*dwidz+sp*dwipdz) |
911 |
< |
fyii = a(2,i)*(s*dwidx+sp*dwipdx) + & |
912 |
< |
a(5,i)*(s*dwidy+sp*dwipdy) + & |
913 |
< |
a(8,i)*(s*dwidz+sp*dwipdz) |
914 |
< |
fzii = a(3,i)*(s*dwidx+sp*dwipdx) + & |
915 |
< |
a(6,i)*(s*dwidy+sp*dwipdy) + & |
916 |
< |
a(9,i)*(s*dwidz+sp*dwipdz) |
917 |
< |
|
918 |
< |
fxij = -fxii |
919 |
< |
fyij = -fyii |
920 |
< |
fzij = -fzii |
921 |
< |
|
922 |
< |
fxjj = a(1,j)*(s*dwjdx+sp*dwjpdx) + & |
923 |
< |
a(4,j)*(s*dwjdy+sp*dwjpdy) + & |
924 |
< |
a(7,j)*(s*dwjdz+sp*dwjpdz) |
925 |
< |
fyjj = a(2,j)*(s*dwjdx+sp*dwjpdx) + & |
926 |
< |
a(5,j)*(s*dwjdy+sp*dwjpdy) + & |
927 |
< |
a(8,j)*(s*dwjdz+sp*dwjpdz) |
928 |
< |
fzjj = a(3,j)*(s*dwjdx+sp*dwjpdx)+ & |
929 |
< |
a(6,j)*(s*dwjdy+sp*dwjpdy) + & |
930 |
< |
a(9,j)*(s*dwjdz+sp*dwjpdz) |
931 |
< |
|
932 |
< |
fxji = -fxjj |
933 |
< |
fyji = -fyjj |
934 |
< |
fzji = -fzjj |
935 |
< |
|
936 |
< |
! now assemble these with the radial-only terms: |
937 |
< |
|
938 |
< |
flx(atom1) = flx(atom1) + 0.5d0*SSD_v0*(dsdr*drdx*w + dspdr*drdx*wp + & |
939 |
< |
fxii + fxji) |
940 |
< |
fly(atom1) = fly(atom1) + 0.5d0*SSD_v0*(dsdr*drdy*w + dspdr*drdy*wp + & |
941 |
< |
fyii + fyji) |
942 |
< |
flz(atom1) = flz(atom1) + 0.5d0*SSD_v0*(dsdr*drdz*w + dspdr*drdz*wp + & |
943 |
< |
fzii + fzji) |
944 |
< |
|
945 |
< |
flx(atom2) = flx(atom2) + 0.5d0*SSD_v0*(-dsdr*drdx*w - dspdr*drdx*wp + & |
946 |
< |
fxjj + fxij) |
947 |
< |
fly(atom2) = fly(atom2) + 0.5d0*SSD_v0*(-dsdr*drdy*w - dspdr*drdy*wp + & |
948 |
< |
fyjj + fyij) |
949 |
< |
flz(atom2) = flz(atom2) + 0.5d0*SSD_v0*(-dsdr*drdz*w - dspdr*drdz*wp + & |
950 |
< |
fzjj + fzij) |
951 |
< |
|
952 |
< |
end subroutine getSSDSticky |
953 |
< |
|
954 |
< |
!! calculates the switching functions and their derivatives for a given |
955 |
< |
subroutine calc_sw_fnc(r, s, sp, dsdr, dspdr) |
956 |
< |
|
957 |
< |
|
958 |
< |
! value of r |
959 |
< |
|
960 |
< |
double precision r, s, sp, dsdr, dspdr |
961 |
< |
double precision rl, ru, rup |
962 |
< |
! distances are in angstroms |
963 |
< |
parameter(rl = 2.75d0, ru = 3.35d0, rup = 4.0d0) |
964 |
< |
|
965 |
< |
if (r.lt.rl) then |
966 |
< |
s = 1.0d0 |
967 |
< |
sp = 1.0d0 |
968 |
< |
dsdr = 0.0d0 |
969 |
< |
dspdr = 0.0d0 |
970 |
< |
elseif (r.gt.rup) then |
971 |
< |
s = 0.0d0 |
972 |
< |
sp = 0.0d0 |
973 |
< |
dsdr = 0.0d0 |
974 |
< |
dspdr = 0.0d0 |
975 |
< |
else |
976 |
< |
sp = ((rup + 2.0d0*r - 3.0d0*rl) * (rup-r)**2)/((rup - rl)**3) |
977 |
< |
dspdr = 6.0d0*(r-rup)*(r-rl)/((rup - rl)**3) |
978 |
< |
|
979 |
< |
if (r.gt.ru) then |
980 |
< |
s = 0.0d0 |
981 |
< |
dsdr = 0.0d0 |
982 |
< |
else |
983 |
< |
s = ((ru + 2.0d0*r - 3.0d0*rl) * (ru-r)**2)/((ru - rl)**3) |
984 |
< |
dsdr = 6.0d0*(r-ru)*(r-rl)/((ru - rl)**3) |
985 |
< |
endif |
986 |
< |
endif |
987 |
< |
|
988 |
< |
return |
989 |
< |
end subroutine calc_sw_fnc |
990 |
< |
|
991 |
< |
|
992 |
< |
|
993 |
< |
|
994 |
< |
|
995 |
< |
|
996 |
< |
|
997 |
< |
|
998 |
< |
|
999 |
< |
!! Calculates the mixing for sigma or epslon based on character string for initialzition of mixing array. |
1000 |
< |
function calcMix(thisParam,param1,param2,status) result(myMixParam) |
1001 |
< |
character(len=*) :: thisParam |
1002 |
< |
real(kind = dp) :: param1 |
1003 |
< |
real(kind = dp) :: param2 |
1004 |
< |
real(kind = dp ) :: myMixParam |
1005 |
< |
integer, optional :: status |
1006 |
< |
|
1007 |
< |
|
1008 |
< |
myMixParam = 0.0_dp |
1009 |
< |
|
1010 |
< |
if (present(status)) status = 0 |
1011 |
< |
|
1012 |
< |
select case (thisParam) |
1013 |
< |
|
1014 |
< |
case ("sigma") |
1015 |
< |
myMixParam = 0.5_dp * (param1 + param2) |
1016 |
< |
case ("epsilon") |
1017 |
< |
myMixParam = sqrt(param1 * param2) |
1018 |
< |
case default |
1019 |
< |
status = -1 |
1020 |
< |
end select |
1021 |
< |
|
1022 |
< |
end function calcMix |
1023 |
< |
|
1024 |
< |
|
1025 |
< |
|
1026 |
< |
|
1027 |
< |
|
1028 |
< |
|
1029 |
< |
end module lj_ff |
373 |
> |
|
374 |
> |
return |
375 |
> |
end subroutine calc_sw_fnc |
376 |
> |
end module sticky_pair |