ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/SHAPES/calc_shapes.f90
Revision: 1360
Committed: Tue Jul 20 20:02:15 2004 UTC (19 years, 11 months ago) by gezelter
File size: 29527 byte(s)
Log Message:
Changes for CGI and for gengetopts --unamed-opt="PDBFILE"

File Contents

# User Rev Content
1 gezelter 1314 module shapes
2 gezelter 1360
3     use force_globals
4     use definitions
5     use atype_module
6     use vector_class
7     use simulation
8     use status
9     #ifdef IS_MPI
10     use mpiSimulation
11     #endif
12 gezelter 1314 implicit none
13 gezelter 1360
14 gezelter 1314 PRIVATE
15 gezelter 1360
16 gezelter 1314 INTEGER, PARAMETER:: CHEBYSHEV_TN = 1
17     INTEGER, PARAMETER:: CHEBYSHEV_UN = 2
18     INTEGER, PARAMETER:: LAGUERRE = 3
19     INTEGER, PARAMETER:: HERMITE = 4
20 gezelter 1360 logical, save :: haveShapeMap = .false.
21 gezelter 1314
22 gezelter 1360 public :: do_shape_pair
23 gezelter 1314
24 gezelter 1360 type :: ShapeList
25     integer :: nLMpairs = 0
26     integer :: bigL = 0
27     integer :: bigM = 0
28     integer, allocatable, dimension(:) :: lValue
29     integer, allocatable, dimension(:) :: mValue
30     real(kind=dp), allocatable, dimension(:) :: contactFuncSinCoeff
31     real(kind=dp), allocatable, dimension(:) :: contactFuncCosCoeff
32     real(kind=dp), allocatable, dimension(:) :: rangeFuncSinCoeff
33     real(kind=dp), allocatable, dimension(:) :: rangeFuncCosCoeff
34     real(kind=dp), allocatable, dimension(:) :: strengthFuncSinCoeff
35     real(kind=dp), allocatable, dimension(:) :: strengthFuncCosCoeff
36     integer, allocatable, dimension(:) :: mValue
37     logical :: isLJ = .false.
38     real ( kind = dp ) :: epsilon = 0.0_dp
39     real ( kind = dp ) :: sigma = 0.0_dp
40     end type ShapeList
41 gezelter 1314
42 gezelter 1360 type(ShapeList), dimension(:),allocatable :: ShapeMap
43 gezelter 1314
44    
45 gezelter 1360 contains
46 gezelter 1314
47 gezelter 1360 subroutine do_shape_pair(atom1, atom2, d, rij, r2, sw, vpair, fpair, &
48     pot, A, f, t, do_pot)
49    
50     !! We assume that the rotation matrices have already been calculated
51     !! and placed in the A array.
52    
53     r3 = r2*rij
54     r5 = r3*r2
55    
56     drdx = d(1) / rij
57     drdy = d(2) / rij
58     drdz = d(3) / rij
59    
60     #ifdef IS_MPI
61     me1 = atid_Row(atom1)
62     me2 = atid_Col(atom2)
63     #else
64     me1 = atid(atom1)
65     me2 = atid(atom2)
66     #endif
67 gezelter 1314
68 gezelter 1360 if (ShapeMap(me1)%isLJ) then
69     sigma_i = ShapeMap(me1)%sigma
70     s_i = ShapeMap(me1)%sigma
71     eps_i = ShapeMap(me1)%epsilon
72     dsigmaidx = 0.0d0
73     dsigmaidy = 0.0d0
74     dsigmaidz = 0.0d0
75     dsigmaidux = 0.0d0
76     dsigmaiduy = 0.0d0
77     dsigmaiduz = 0.0d0
78     dsidx = 0.0d0
79     dsidy = 0.0d0
80     dsidz = 0.0d0
81     dsidux = 0.0d0
82     dsiduy = 0.0d0
83     dsiduz = 0.0d0
84     depsidx = 0.0d0
85     depsidy = 0.0d0
86     depsidz = 0.0d0
87     depsidux = 0.0d0
88     depsiduy = 0.0d0
89     depsiduz = 0.0d0
90     else
91 gezelter 1314
92 gezelter 1360 #ifdef IS_MPI
93     ! rotate the inter-particle separation into the two different
94     ! body-fixed coordinate systems:
95    
96     xi = A_row(1,atom1)*d(1) + A_row(2,atom1)*d(2) + A_row(3,atom1)*d(3)
97     yi = A_row(4,atom1)*d(1) + A_row(5,atom1)*d(2) + A_row(6,atom1)*d(3)
98     zi = A_row(7,atom1)*d(1) + A_row(8,atom1)*d(2) + A_row(9,atom1)*d(3)
99    
100     #else
101     ! rotate the inter-particle separation into the two different
102     ! body-fixed coordinate systems:
103    
104     xi = a(1,atom1)*d(1) + a(2,atom1)*d(2) + a(3,atom1)*d(3)
105     yi = a(4,atom1)*d(1) + a(5,atom1)*d(2) + a(6,atom1)*d(3)
106     zi = a(7,atom1)*d(1) + a(8,atom1)*d(2) + a(9,atom1)*d(3)
107    
108     #endif
109    
110     xi2 = xi*xi
111     yi2 = yi*yi
112     zi2 = zi*zi
113    
114     proji = sqrt(xi2 + yi2)
115     proji3 = proji*proji*proji
116    
117     cti = zi / rij
118     dctidx = - zi * xi / r3
119     dctidy = - zi * yi / r3
120     dctidz = 1.0d0 / rij - zi2 / r3
121     dctidux = yi / rij
122     dctiduy = -xi / rij
123     dctiduz = 0.0d0
124    
125     cpi = xi / proji
126     dcpidx = 1.0d0 / proji - xi2 / proji3
127     dcpidy = - xi * yi / proji3
128     dcpidz = 0.0d0
129     dcpidux = xi * yi * zi / proji3
130     dcpiduy = -zi * (1.0d0 / proji - xi2 / proji3)
131     dcpiduz = -yi * (1.0d0 / proji - xi2 / proji3) - (xi2 * yi / proji3)
132    
133     spi = yi / proji
134     dspidx = - xi * yi / proji3
135     dspidy = 1.0d0 / proji - yi2 / proji3
136     dspidz = 0.0d0
137     dspidux = -zi * (1.0d0 / proji - yi2 / proji3)
138     dspiduy = xi * yi * zi / proji3
139     dspiduz = xi * (1.0d0 / proji - yi2 / proji3) + (xi * yi2 / proji3)
140 gezelter 1314
141 gezelter 1360 call Associated_Legendre(cti, ShapeMap(me1)%bigL, &
142     ShapeMap(me1)%bigM, lmax, plm_i, dlm_i)
143 gezelter 1314
144 gezelter 1360 call Orthogonal_Polynomial(cpi, ShapeMap(me1)%bigM, CHEBYSHEV_TN, &
145     tm_i, dtm_i)
146     call Orthogonal_Polynomial(cpi, ShapeMap(me1)%bigM, CHEBYSHEV_UN, &
147     um_i, dum_i)
148    
149     sigma_i = 0.0d0
150     s_i = 0.0d0
151     eps_i = 0.0d0
152     dsigmaidx = 0.0d0
153     dsigmaidy = 0.0d0
154     dsigmaidz = 0.0d0
155     dsigmaidux = 0.0d0
156     dsigmaiduy = 0.0d0
157     dsigmaiduz = 0.0d0
158     dsidx = 0.0d0
159     dsidy = 0.0d0
160     dsidz = 0.0d0
161     dsidux = 0.0d0
162     dsiduy = 0.0d0
163     dsiduz = 0.0d0
164     depsidx = 0.0d0
165     depsidy = 0.0d0
166     depsidz = 0.0d0
167     depsidux = 0.0d0
168     depsiduy = 0.0d0
169     depsiduz = 0.0d0
170    
171     do lm = 1, ShapeMap(me1)%nLMpairs
172    
173     l = ShapeMap(me1)%lValue(lm)
174     m = ShapeMap(me1)%mValue(lm)
175    
176     slm = ShapeMap(me1)%contactFuncSinCoeff(lm)
177     clm = ShapeMap(me1)%contactFuncCosCoeff(lm)
178    
179     Phunc = (slm * spi * um_i(m-1) + clm * tm_i(m))
180    
181     dPhuncdX = (slm * (spi * dum_i(m-1) * dcpidx + dspidx * um_i(m-1)) &
182     + clm * dtm_i(m) * dcpidx )
183     dPhuncdY = (slm * (spi * dum_i(m-1) * dcpidy + dspidy * um_i(m-1)) &
184     + clm * dtm_i(m) * dcpidy )
185     dPhuncdZ = (slm * (spi * dum_i(m-1) * dcpidz + dspidz * um_i(m-1)) &
186     + clm * dtm_i(m) * dcpidz )
187    
188     dPhuncdUx = (slm*(spi * dum_i(m-1) * dcpidux + dspidux * um_i(m-1)) &
189     + clm * dtm_i(m) * dcpidux
190     dPhuncdUy = (slm*(spi * dum_i(m-1) * dcpiduy + dspiduy * um_i(m-1)) &
191     + clm * dtm_i(m) * dcpiduy
192     dPhuncdUz = (slm*(spi * dum_i(m-1) * dcpiduz + dspiduz * um_i(m-1)) &
193     + clm * dtm_i(m) * dcpiduz
194    
195     sigma_i = sigma_i + plm_i(l,m)*Phunc
196    
197     dsigmaidx = dsigmaidx + plm_i(l,m)*dPhuncdX + &
198     Phunc * dlm_i(l,m) * dctidx
199     dsigmaidy = dsigmaidy + plm_i(l,m)*dPhuncdY + &
200     Phunc * dlm_i(l,m) * dctidy
201     dsigmaidz = dsigmaidz + plm_i(l,m)*dPhuncdZ + &
202     Phunc * dlm_i(l,m) * dctidz
203    
204     dsigmaidux = dsigmaidux + plm_i(l,m)* dPhuncdUx + &
205     Phunc * dlm_i(l,m) * dctidux
206     dsigmaiduy = dsigmaiduy + plm_i(l,m)* dPhuncdUy + &
207     Phunc * dlm_i(l,m) * dctiduy
208     dsigmaiduz = dsigmaiduz + plm_i(l,m)* dPhuncdUz + &
209     Phunc * dlm_i(l,m) * dctiduz
210    
211     slm = ShapeMap(me1)%rangeFuncSinCoeff(lm)
212     clm = ShapeMap(me1)%rangeFuncCosCoeff(lm)
213    
214     Phunc = (slm * spi * um_i(m-1) + clm * tm_i(m))
215    
216     dPhuncdX = (slm * (spi * dum_i(m-1) * dcpidx + dspidx * um_i(m-1)) &
217     + clm * dtm_i(m) * dcpidx )
218     dPhuncdY = (slm * (spi * dum_i(m-1) * dcpidy + dspidy * um_i(m-1)) &
219     + clm * dtm_i(m) * dcpidy )
220     dPhuncdZ = (slm * (spi * dum_i(m-1) * dcpidz + dspidz * um_i(m-1)) &
221     + clm * dtm_i(m) * dcpidz )
222    
223     dPhuncdUx = (slm*(spi * dum_i(m-1) * dcpidux + dspidux * um_i(m-1)) &
224     + clm * dtm_i(m) * dcpidux
225     dPhuncdUy = (slm*(spi * dum_i(m-1) * dcpiduy + dspiduy * um_i(m-1)) &
226     + clm * dtm_i(m) * dcpiduy
227     dPhuncdUz = (slm*(spi * dum_i(m-1) * dcpiduz + dspiduz * um_i(m-1)) &
228     + clm * dtm_i(m) * dcpiduz
229    
230     s_i = s_i + plm_i(l,m)*Phunc
231    
232     dsidx = dsidx + plm_i(l,m)*dPhuncdX + &
233     Phunc * dlm_i(l,m) * dctidx
234     dsidy = dsidy + plm_i(l,m)*dPhuncdY + &
235     Phunc * dlm_i(l,m) * dctidy
236     dsidz = dsidz + plm_i(l,m)*dPhuncdZ + &
237     Phunc * dlm_i(l,m) * dctidz
238    
239     dsidux = dsidux + plm_i(l,m)* dPhuncdUx + &
240     Phunc * dlm_i(l,m) * dctidux
241     dsiduy = dsiduy + plm_i(l,m)* dPhuncdUy + &
242     Phunc * dlm_i(l,m) * dctiduy
243     dsiduz = dsiduz + plm_i(l,m)* dPhuncdUz + &
244     Phunc * dlm_i(l,m) * dctiduz
245    
246     slm = ShapeMap(me1)%strengthFuncSinCoeff(lm)
247     clm = ShapeMap(me1)%strengthFuncCosCoeff(lm)
248    
249     Phunc = (slm * spi * um_i(m-1) + clm * tm_i(m))
250    
251     dPhuncdX = (slm * (spi * dum_i(m-1) * dcpidx + dspidx * um_i(m-1)) &
252     + clm * dtm_i(m) * dcpidx )
253     dPhuncdY = (slm * (spi * dum_i(m-1) * dcpidy + dspidy * um_i(m-1)) &
254     + clm * dtm_i(m) * dcpidy )
255     dPhuncdZ = (slm * (spi * dum_i(m-1) * dcpidz + dspidz * um_i(m-1)) &
256     + clm * dtm_i(m) * dcpidz )
257    
258     dPhuncdUx = (slm*(spi * dum_i(m-1) * dcpidux + dspidux * um_i(m-1)) &
259     + clm * dtm_i(m) * dcpidux
260     dPhuncdUy = (slm*(spi * dum_i(m-1) * dcpiduy + dspiduy * um_i(m-1)) &
261     + clm * dtm_i(m) * dcpiduy
262     dPhuncdUz = (slm*(spi * dum_i(m-1) * dcpiduz + dspiduz * um_i(m-1)) &
263     + clm * dtm_i(m) * dcpiduz
264    
265     eps_i = eps_i + plm_i(l,m)*Phunc
266    
267     depsidx = depsidx + plm_i(l,m)*dPhuncdX + &
268     Phunc * dlm_i(l,m) * dctidx
269     depsidy = depsidy + plm_i(l,m)*dPhuncdY + &
270     Phunc * dlm_i(l,m) * dctidy
271     depsidz = depsidz + plm_i(l,m)*dPhuncdZ + &
272     Phunc * dlm_i(l,m) * dctidz
273    
274     depsidux = depsidux + plm_i(l,m)* dPhuncdUx + &
275     Phunc * dlm_i(l,m) * dctidux
276     depsiduy = depsiduy + plm_i(l,m)* dPhuncdUy + &
277     Phunc * dlm_i(l,m) * dctiduy
278     depsiduz = depsiduz + plm_i(l,m)* dPhuncdUz + &
279     Phunc * dlm_i(l,m) * dctiduz
280    
281     enddo
282     endif
283    
284     ! now do j:
285 gezelter 1314
286 gezelter 1360 if (ShapeMap(me2)%isLJ) then
287     sigma_j = ShapeMap(me2)%sigma
288     s_j = ShapeMap(me2)%sigma
289     eps_j = ShapeMap(me2)%epsilon
290     dsigmajdx = 0.0d0
291     dsigmajdy = 0.0d0
292     dsigmajdz = 0.0d0
293     dsigmajdux = 0.0d0
294     dsigmajduy = 0.0d0
295     dsigmajduz = 0.0d0
296     dsjdx = 0.0d0
297     dsjdy = 0.0d0
298     dsjdz = 0.0d0
299     dsjdux = 0.0d0
300     dsjduy = 0.0d0
301     dsjduz = 0.0d0
302     depsjdx = 0.0d0
303     depsjdy = 0.0d0
304     depsjdz = 0.0d0
305     depsjdux = 0.0d0
306     depsjduy = 0.0d0
307     depsjduz = 0.0d0
308     else
309    
310     #ifdef IS_MPI
311     ! rotate the inter-particle separation into the two different
312     ! body-fixed coordinate systems:
313     ! negative sign because this is the vector from j to i:
314    
315     xj = -(A_Col(1,atom2)*d(1) + A_Col(2,atom2)*d(2) + A_Col(3,atom2)*d(3))
316     yj = -(A_Col(4,atom2)*d(1) + A_Col(5,atom2)*d(2) + A_Col(6,atom2)*d(3))
317     zj = -(A_Col(7,atom2)*d(1) + A_Col(8,atom2)*d(2) + A_Col(9,atom2)*d(3))
318     #else
319     ! rotate the inter-particle separation into the two different
320     ! body-fixed coordinate systems:
321     ! negative sign because this is the vector from j to i:
322    
323     xj = -(a(1,atom2)*d(1) + a(2,atom2)*d(2) + a(3,atom2)*d(3))
324     yj = -(a(4,atom2)*d(1) + a(5,atom2)*d(2) + a(6,atom2)*d(3))
325     zj = -(a(7,atom2)*d(1) + a(8,atom2)*d(2) + a(9,atom2)*d(3))
326     #endif
327    
328     xj2 = xj*xj
329     yj2 = yj*yj
330     zj2 = zj*zj
331    
332     projj = sqrt(xj2 + yj2)
333     projj3 = projj*projj*projj
334    
335     ctj = zj / rij
336     dctjdx = - zj * xj / r3
337     dctjdy = - zj * yj / r3
338     dctjdz = 1.0d0 / rij - zj2 / r3
339     dctjdux = yj / rij
340     dctjduy = -xj / rij
341     dctjduz = 0.0d0
342    
343     cpj = xj / projj
344     dcpjdx = 1.0d0 / projj - xj2 / projj3
345     dcpjdy = - xj * yj / projj3
346     dcpjdz = 0.0d0
347     dcpjdux = xj * yj * zj / projj3
348     dcpjduy = -zj * (1.0d0 / projj - xj2 / projj3)
349     dcpjduz = -yj * (1.0d0 / projj - xj2 / projj3) - (xj2 * yj / projj3)
350    
351     spj = yj / projj
352     dspjdx = - xj * yj / projj3
353     dspjdy = 1.0d0 / projj - yj2 / projj3
354     dspjdz = 0.0d0
355     dspjdux = -zj * (1.0d0 / projj - yj2 / projj3)
356     dspjduy = xj * yj * zj / projj3
357     dspjduz = xj * (1.0d0 / projj - yi2 / projj3) + (xj * yj2 / projj3)
358    
359     call Associated_Legendre(ctj, ShapeMap(me2)%bigL, &
360     ShapeMap(me2)%bigM, lmax, plm_j, dlm_j)
361    
362     call Orthogonal_Polynomial(cpj, ShapeMap(me2)%bigM, CHEBYSHEV_TN, &
363     tm_j, dtm_j)
364     call Orthogonal_Polynomial(cpj, ShapeMap(me2)%bigM, CHEBYSHEV_UN, &
365     um_j, dum_j)
366    
367     sigma_j = 0.0d0
368     s_j = 0.0d0
369     eps_j = 0.0d0
370     dsigmajdx = 0.0d0
371     dsigmajdy = 0.0d0
372     dsigmajdz = 0.0d0
373     dsigmajdux = 0.0d0
374     dsigmajduy = 0.0d0
375     dsigmajduz = 0.0d0
376     dsjdx = 0.0d0
377     dsjdy = 0.0d0
378     dsjdz = 0.0d0
379     dsjdux = 0.0d0
380     dsjduy = 0.0d0
381     dsjduz = 0.0d0
382     depsjdx = 0.0d0
383     depsjdy = 0.0d0
384     depsjdz = 0.0d0
385     depsjdux = 0.0d0
386     depsjduy = 0.0d0
387     depsjduz = 0.0d0
388    
389     do lm = 1, ShapeMap(me2)%nLMpairs
390    
391     l = ShapeMap(me2)%lValue(lm)
392     m = ShapeMap(me2)%mValue(lm)
393    
394     slm = ShapeMap(me2)%contactFuncSinCoeff(lm)
395     clm = ShapeMap(me2)%contactFuncCosCoeff(lm)
396    
397     Phunc = (slm * spi * um_i(m-1) + clm * tm_i(m))
398    
399     dPhuncdX = (slm * (spj * dum_j(m-1) * dcpjdx + dspjdx * um_j(m-1)) &
400     + clm * dtm_j(m) * dcpjdx )
401     dPhuncdY = (slm * (spj * dum_j(m-1) * dcpjdy + dspjdy * um_j(m-1)) &
402     + clm * dtm_j(m) * dcpjdy )
403     dPhuncdZ = (slm * (spj * dum_j(m-1) * dcpjdz + dspjdz * um_j(m-1)) &
404     + clm * dtm_j(m) * dcpjdz )
405    
406     dPhuncdUx = (slm*(spj * dum_j(m-1) * dcpjdux + dspjdux * um_j(m-1)) &
407     + clm * dtm_j(m) * dcpjdux
408     dPhuncdUy = (slm*(spj * dum_j(m-1) * dcpjduy + dspjduy * um_j(m-1)) &
409     + clm * dtm_j(m) * dcpjduy
410     dPhuncdUz = (slm*(spj * dum_j(m-1) * dcpjduz + dspjduz * um_j(m-1)) &
411     + clm * dtm_j(m) * dcpjduz
412    
413     sigma_j = sigma_j + plm_j(l,m)*Phunc
414    
415     dsigmajdx = dsigmajdx + plm_j(l,m)*dPhuncdX + &
416     Phunc * dlm_j(l,m) * dctjdx
417     dsigmajdy = dsigmajdy + plm_j(l,m)*dPhuncdY + &
418     Phunc * dlm_j(l,m) * dctjdy
419     dsigmajdz = dsigmajdz + plm_j(l,m)*dPhuncdZ + &
420     Phunc * dlm_j(l,m) * dctjdz
421    
422     dsigmajdux = dsigmajdux + plm_j(l,m)* dPhuncdUx + &
423     Phunc * dlm_j(l,m) * dctjdux
424     dsigmajduy = dsigmajduy + plm_j(l,m)* dPhuncdUy + &
425     Phunc * dlm_j(l,m) * dctjduy
426     dsigmajduz = dsigmajduz + plm_j(l,m)* dPhuncdUz + &
427     Phunc * dlm_j(l,m) * dctjduz
428    
429     slm = ShapeMap(me2)%rangeFuncSinCoeff(lm)
430     clm = ShapeMap(me2)%rangeFuncCosCoeff(lm)
431 gezelter 1314
432 gezelter 1360 Phunc = (slm * spi * um_i(m-1) + clm * tm_i(m))
433    
434     dPhuncdX = (slm * (spj * dum_j(m-1) * dcpjdx + dspjdx * um_j(m-1)) &
435     + clm * dtm_j(m) * dcpjdx )
436     dPhuncdY = (slm * (spj * dum_j(m-1) * dcpjdy + dspjdy * um_j(m-1)) &
437     + clm * dtm_j(m) * dcpjdy )
438     dPhuncdZ = (slm * (spj * dum_j(m-1) * dcpjdz + dspjdz * um_j(m-1)) &
439     + clm * dtm_j(m) * dcpjdz )
440    
441     dPhuncdUx = (slm*(spj * dum_j(m-1) * dcpjdux + dspjdux * um_j(m-1)) &
442     + clm * dtm_j(m) * dcpjdux
443     dPhuncdUy = (slm*(spj * dum_j(m-1) * dcpjduy + dspjduy * um_j(m-1)) &
444     + clm * dtm_j(m) * dcpjduy
445     dPhuncdUz = (slm*(spj * dum_j(m-1) * dcpjduz + dspjduz * um_j(m-1)) &
446     + clm * dtm_j(m) * dcpjduz
447    
448     s_j = s_j + plm_j(l,m)*Phunc
449    
450     dsjdx = dsjdx + plm_j(l,m)*dPhuncdX + &
451     Phunc * dlm_j(l,m) * dctjdx
452     dsjdy = dsjdy + plm_j(l,m)*dPhuncdY + &
453     Phunc * dlm_j(l,m) * dctjdy
454     dsjdz = dsjdz + plm_j(l,m)*dPhuncdZ + &
455     Phunc * dlm_j(l,m) * dctjdz
456    
457     dsjdux = dsjdux + plm_j(l,m)* dPhuncdUx + &
458     Phunc * dlm_j(l,m) * dctjdux
459     dsjduy = dsjduy + plm_j(l,m)* dPhuncdUy + &
460     Phunc * dlm_j(l,m) * dctjduy
461     dsjduz = dsjduz + plm_j(l,m)* dPhuncdUz + &
462     Phunc * dlm_j(l,m) * dctjduz
463    
464     slm = ShapeMap(me2)%strengthFuncSinCoeff(lm)
465     clm = ShapeMap(me2)%strengthFuncCosCoeff(lm)
466    
467     Phunc = (slm * spi * um_i(m-1) + clm * tm_i(m))
468    
469     dPhuncdX = (slm * (spj * dum_j(m-1) * dcpjdx + dspjdx * um_j(m-1)) &
470     + clm * dtm_j(m) * dcpjdx )
471     dPhuncdY = (slm * (spj * dum_j(m-1) * dcpjdy + dspjdy * um_j(m-1)) &
472     + clm * dtm_j(m) * dcpjdy )
473     dPhuncdZ = (slm * (spj * dum_j(m-1) * dcpjdz + dspjdz * um_j(m-1)) &
474     + clm * dtm_j(m) * dcpjdz )
475    
476     dPhuncdUx = (slm*(spj * dum_j(m-1) * dcpjdux + dspjdux * um_j(m-1)) &
477     + clm * dtm_j(m) * dcpjdux
478     dPhuncdUy = (slm*(spj * dum_j(m-1) * dcpjduy + dspjduy * um_j(m-1)) &
479     + clm * dtm_j(m) * dcpjduy
480     dPhuncdUz = (slm*(spj * dum_j(m-1) * dcpjduz + dspjduz * um_j(m-1)) &
481     + clm * dtm_j(m) * dcpjduz
482    
483     eps_j = eps_j + plm_j(l,m)*Phunc
484    
485     depsjdx = depsjdx + plm_j(l,m)*dPhuncdX + &
486     Phunc * dlm_j(l,m) * dctjdx
487     depsjdy = depsjdy + plm_j(l,m)*dPhuncdY + &
488     Phunc * dlm_j(l,m) * dctjdy
489     depsjdz = depsjdz + plm_j(l,m)*dPhuncdZ + &
490     Phunc * dlm_j(l,m) * dctjdz
491    
492     depsjdux = depsjdux + plm_j(l,m)* dPhuncdUx + &
493     Phunc * dlm_j(l,m) * dctjdux
494     depsjduy = depsjduy + plm_j(l,m)* dPhuncdUy + &
495     Phunc * dlm_j(l,m) * dctjduy
496     depsjduz = depsjduz + plm_j(l,m)* dPhuncdUz + &
497     Phunc * dlm_j(l,m) * dctjduz
498    
499     enddo
500     endif
501 gezelter 1314
502 gezelter 1360 ! phew, now let's assemble the potential energy:
503    
504    
505     sigma = 0.5*(sigma_i + sigma_j)
506    
507     dsigmadxi = 0.5*dsigmaidx
508     dsigmadyi = 0.5*dsigmaidy
509     dsigmadzi = 0.5*dsigmaidz
510     dsigmaduxi = 0.5*dsigmaidux
511     dsigmaduyi = 0.5*dsigmaiduy
512     dsigmaduzi = 0.5*dsigmaiduz
513    
514     dsigmadxj = 0.5*dsigmajdx
515     dsigmadyj = 0.5*dsigmajdy
516     dsigmadzj = 0.5*dsigmajdz
517     dsigmaduxj = 0.5*dsigmajdux
518     dsigmaduyj = 0.5*dsigmajduy
519     dsigmaduzj = 0.5*dsigmajduz
520    
521     s = 0.5*(s_i + s_j)
522    
523     dsdxi = 0.5*dsidx
524     dsdyi = 0.5*dsidy
525     dsdzi = 0.5*dsidz
526     dsduxi = 0.5*dsidux
527     dsduyi = 0.5*dsiduy
528     dsduzi = 0.5*dsiduz
529    
530     dsdxj = 0.5*dsjdx
531     dsdyj = 0.5*dsjdy
532     dsdzj = 0.5*dsjdz
533     dsduxj = 0.5*dsjdux
534     dsduyj = 0.5*dsjduy
535     dsduzj = 0.5*dsjduz
536    
537     eps = sqrt(eps_i * eps_j)
538    
539     depsdxi = eps_j * depsidx / (2.0d0 * eps)
540     depsdyi = eps_j * depsidy / (2.0d0 * eps)
541     depsdzi = eps_j * depsidz / (2.0d0 * eps)
542     depsduxi = eps_j * depsidux / (2.0d0 * eps)
543     depsduyi = eps_j * depsiduy / (2.0d0 * eps)
544     depsduzi = eps_j * depsiduz / (2.0d0 * eps)
545    
546     depsdxj = eps_i * depsjdx / (2.0d0 * eps)
547     depsdyj = eps_i * depsjdy / (2.0d0 * eps)
548     depsdzj = eps_i * depsjdz / (2.0d0 * eps)
549     depsduxj = eps_i * depsjdux / (2.0d0 * eps)
550     depsduyj = eps_i * depsjduy / (2.0d0 * eps)
551     depsduzj = eps_i * depsjduz / (2.0d0 * eps)
552    
553     rtdenom = r-sigma+s
554     rt = s / rtdenom
555    
556     drtdxi = (dsdxi + rt * (drdxi - dsigmadxi + dsdxi)) / rtdenom
557     drtdyi = (dsdyi + rt * (drdyi - dsigmadyi + dsdyi)) / rtdenom
558     drtdzi = (dsdzi + rt * (drdzi - dsigmadzi + dsdzi)) / rtdenom
559     drtduxi = (dsduxi + rt * (drduxi - dsigmaduxi + dsduxi)) / rtdenom
560     drtduyi = (dsduyi + rt * (drduyi - dsigmaduyi + dsduyi)) / rtdenom
561     drtduzi = (dsduzi + rt * (drduzi - dsigmaduzi + dsduzi)) / rtdenom
562     drtdxj = (dsdxj + rt * (drdxj - dsigmadxj + dsdxj)) / rtdenom
563     drtdyj = (dsdyj + rt * (drdyj - dsigmadyj + dsdyj)) / rtdenom
564     drtdzj = (dsdzj + rt * (drdzj - dsigmadzj + dsdzj)) / rtdenom
565     drtduxj = (dsduxj + rt * (drduxj - dsigmaduxj + dsduxj)) / rtdenom
566     drtduyj = (dsduyj + rt * (drduyj - dsigmaduyj + dsduyj)) / rtdenom
567     drtduzj = (dsduzj + rt * (drduzj - dsigmaduzj + dsduzj)) / rtdenom
568    
569     rt2 = rt*rt
570     rt3 = rt2*rt
571     rt5 = rt2*rt3
572     rt6 = rt3*rt3
573     rt11 = rt5*rt6
574     rt12 = rt6*rt6
575     rt126 = rt12 - rt6
576    
577     if (do_pot) then
578     #ifdef IS_MPI
579     pot_row(atom1) = pot_row(atom1) + 2.0d0*eps*rt126*sw
580     pot_col(atom2) = pot_col(atom2) + 2.0d0*eps*rt126*sw
581     #else
582     pot = pot + 4.0d0*eps*rt126*sw
583     endif
584    
585     dvdxi = 24.0d0*eps(2.0d0*rt11 - rt5)*drtdxi + 4.0d0*depsdxi*rt126
586     dvdyi = 24.0d0*eps(2.0d0*rt11 - rt5)*drtdyi + 4.0d0*depsdyi*rt126
587     dvdzi = 24.0d0*eps(2.0d0*rt11 - rt5)*drtdzi + 4.0d0*depsdzi*rt126
588     dvduxi = 24.0d0*eps(2.0d0*rt11 - rt5)*drtduxi + 4.0d0*depsduxi*rt126
589     dvduyi = 24.0d0*eps(2.0d0*rt11 - rt5)*drtduyi + 4.0d0*depsduyi*rt126
590     dvduzi = 24.0d0*eps(2.0d0*rt11 - rt5)*drtduzi + 4.0d0*depsduzi*rt126
591    
592     dvdxj = 24.0d0*eps(2.0d0*rt11 - rt5)*drtdxj + 4.0d0*depsdxj*rt126
593     dvdyj = 24.0d0*eps(2.0d0*rt11 - rt5)*drtdyj + 4.0d0*depsdyj*rt126
594     dvdzj = 24.0d0*eps(2.0d0*rt11 - rt5)*drtdzj + 4.0d0*depsdzj*rt126
595     dvduxj = 24.0d0*eps(2.0d0*rt11 - rt5)*drtduxj + 4.0d0*depsduxj*rt126
596     dvduyj = 24.0d0*eps(2.0d0*rt11 - rt5)*drtduyj + 4.0d0*depsduyj*rt126
597     dvduzj = 24.0d0*eps(2.0d0*rt11 - rt5)*drtduzj + 4.0d0*depsduzj*rt126
598    
599     ! do the torques first since they are easy:
600     ! remember that these are still in the body fixed axes
601    
602     txi = dvduxi * sw
603     tyi = dvduyi * sw
604     tzi = dvduzi * sw
605    
606     txj = dvduxj * sw
607     tyj = dvduyj * sw
608     tzj = dvduzj * sw
609    
610     ! go back to lab frame using transpose of rotation matrix:
611    
612     #ifdef IS_MPI
613     t_Row(1,atom1) = t_Row(1,atom1) + a_Row(1,atom1)*txi + &
614     a_Row(4,atom1)*tyi + a_Row(7,atom1)*tzi
615     t_Row(2,atom1) = t_Row(2,atom1) + a_Row(2,atom1)*txi + &
616     a_Row(5,atom1)*tyi + a_Row(8,atom1)*tzi
617     t_Row(3,atom1) = t_Row(3,atom1) + a_Row(3,atom1)*txi + &
618     a_Row(6,atom1)*tyi + a_Row(9,atom1)*tzi
619    
620     t_Col(1,atom2) = t_Col(1,atom2) + a_Col(1,atom2)*txj + &
621     a_Col(4,atom2)*tyj + a_Col(7,atom2)*tzj
622     t_Col(2,atom2) = t_Col(2,atom2) + a_Col(2,atom2)*txj + &
623     a_Col(5,atom2)*tyj + a_Col(8,atom2)*tzj
624     t_Col(3,atom2) = t_Col(3,atom2) + a_Col(3,atom2)*txj + &
625     a_Col(6,atom2)*tyj + a_Col(9,atom2)*tzj
626     #else
627     t(1,atom1) = t(1,atom1) + a(1,atom1)*txi + a(4,atom1)*tyi + a(7,atom1)*tzi
628     t(2,atom1) = t(2,atom1) + a(2,atom1)*txi + a(5,atom1)*tyi + a(8,atom1)*tzi
629     t(3,atom1) = t(3,atom1) + a(3,atom1)*txi + a(6,atom1)*tyi + a(9,atom1)*tzi
630    
631     t(1,atom2) = t(1,atom2) + a(1,atom2)*txj + a(4,atom2)*tyj + a(7,atom2)*tzj
632     t(2,atom2) = t(2,atom2) + a(2,atom2)*txj + a(5,atom2)*tyj + a(8,atom2)*tzj
633     t(3,atom2) = t(3,atom2) + a(3,atom2)*txj + a(6,atom2)*tyj + a(9,atom2)*tzj
634     #endif
635     ! Now, on to the forces:
636    
637     ! first rotate the i terms back into the lab frame:
638    
639     fxi = dvdxi * sw
640     fyi = dvdyi * sw
641     fzi = dvdzi * sw
642    
643     fxj = dvdxj * sw
644     fyj = dvdyj * sw
645     fzj = dvdzj * sw
646    
647     #ifdef IS_MPI
648     fxii = a_Row(1,atom1)*fxi + a_Row(4,atom1)*fyi + a_Row(7,atom1)*fzi
649     fyii = a_Row(2,atom1)*fxi + a_Row(5,atom1)*fyi + a_Row(8,atom1)*fzi
650     fzii = a_Row(3,atom1)*fxi + a_Row(6,atom1)*fyi + a_Row(9,atom1)*fzi
651    
652     fxjj = a_Col(1,atom2)*fxj + a_Col(4,atom2)*fyj + a_Col(7,atom2)*fzj
653     fyjj = a_Col(2,atom2)*fxj + a_Col(5,atom2)*fyj + a_Col(8,atom2)*fzj
654     fzjj = a_Col(3,atom2)*fxj + a_Col(6,atom2)*fyj + a_Col(9,atom2)*fzj
655     #else
656     fxii = a(1,atom1)*fxi + a(4,atom1)*fyi + a(7,atom1)*fzi
657     fyii = a(2,atom1)*fxi + a(5,atom1)*fyi + a(8,atom1)*fzi
658     fzii = a(3,atom1)*fxi + a(6,atom1)*fyi + a(9,atom1)*fzi
659    
660     fxjj = a(1,atom2)*fxj + a(4,atom2)*fyj + a(7,atom2)*fzj
661     fyjj = a(2,atom2)*fxj + a(5,atom2)*fyj + a(8,atom2)*fzj
662     fzjj = a(3,atom2)*fxj + a(6,atom2)*fyj + a(9,atom2)*fzj
663     #endif
664    
665     fxij = -fxii
666     fyij = -fyii
667     fzij = -fzii
668    
669     fxji = -fxjj
670     fyji = -fyjj
671     fzji = -fzjj
672    
673     fxradial = fxii + fxji
674     fyradial = fyii + fyji
675     fzradial = fzii + fzji
676    
677     #ifdef IS_MPI
678     f_Row(1,atom1) = f_Row(1,atom1) + fxradial
679     f_Row(2,atom1) = f_Row(2,atom1) + fyradial
680     f_Row(3,atom1) = f_Row(3,atom1) + fzradial
681    
682     f_Col(1,atom2) = f_Col(1,atom2) - fxradial
683     f_Col(2,atom2) = f_Col(2,atom2) - fyradial
684     f_Col(3,atom2) = f_Col(3,atom2) - fzradial
685     #else
686     f(1,atom1) = f(1,atom1) + fxradial
687     f(2,atom1) = f(2,atom1) + fyradial
688     f(3,atom1) = f(3,atom1) + fzradial
689    
690     f(1,atom2) = f(1,atom2) - fxradial
691     f(2,atom2) = f(2,atom2) - fyradial
692     f(3,atom2) = f(3,atom2) - fzradial
693     #endif
694    
695     #ifdef IS_MPI
696     id1 = AtomRowToGlobal(atom1)
697     id2 = AtomColToGlobal(atom2)
698     #else
699     id1 = atom1
700     id2 = atom2
701     #endif
702    
703     if (molMembershipList(id1) .ne. molMembershipList(id2)) then
704    
705     fpair(1) = fpair(1) + fxradial
706     fpair(2) = fpair(2) + fyradial
707     fpair(3) = fpair(3) + fzradial
708    
709     endif
710    
711     end subroutine do_shape_pair
712    
713     SUBROUTINE Associated_Legendre(x, l, m, lmax, plm, dlm)
714    
715     ! Purpose: Compute the associated Legendre functions
716     ! Plm(x) and their derivatives Plm'(x)
717     ! Input : x --- Argument of Plm(x)
718     ! l --- Order of Plm(x), l = 0,1,2,...,n
719     ! m --- Degree of Plm(x), m = 0,1,2,...,N
720     ! lmax --- Physical dimension of PLM and DLM
721     ! Output: PLM(l,m) --- Plm(x)
722     ! DLM(l,m) --- Plm'(x)
723     !
724     ! adapted from the routines in
725     ! COMPUTATION OF SPECIAL FUNCTIONS by Shanjie Zhang and Jianming Jin
726     ! ISBN 0-471-11963-6
727     !
728     ! The original Fortran77 codes can be found here:
729     ! http://iris-lee3.ece.uiuc.edu/~jjin/routines/routines.html
730    
731     real (kind=8), intent(in) :: x
732     integer, intent(in) :: l, m, lmax
733     real (kind=8), dimension(0:lmax,0:m), intent(out) :: PLM, DLM
734     integer :: i, j, ls
735     real (kind=8) :: xq, xs
736    
737     ! zero out both arrays:
738     DO I = 0, m
739     DO J = 0, l
740     PLM(J,I) = 0.0D0
741     DLM(J,I) = 0.0D0
742     end DO
743     end DO
744    
745     ! start with 0,0:
746     PLM(0,0) = 1.0D0
747 gezelter 1314
748 gezelter 1360 ! x = +/- 1 functions are easy:
749     IF (abs(X).EQ.1.0D0) THEN
750     DO I = 1, m
751     PLM(0, I) = X**I
752     DLM(0, I) = 0.5D0*I*(I+1.0D0)*X**(I+1)
753     end DO
754     DO J = 1, m
755     DO I = 1, l
756     IF (I.EQ.1) THEN
757     DLM(I, J) = 1.0D+300
758     ELSE IF (I.EQ.2) THEN
759     DLM(I, J) = -0.25D0*(J+2)*(J+1)*J*(J-1)*X**(J+1)
760     ENDIF
761     end DO
762     end DO
763     RETURN
764     ENDIF
765    
766     LS = 1
767     IF (abs(X).GT.1.0D0) LS = -1
768     XQ = sqrt(LS*(1.0D0-X*X))
769     XS = LS*(1.0D0-X*X)
770    
771     DO I = 1, l
772     PLM(I, I) = -LS*(2.0D0*I-1.0D0)*XQ*PLM(I-1, I-1)
773     enddo
774    
775     DO I = 0, l
776     PLM(I, I+1)=(2.0D0*I+1.0D0)*X*PLM(I, I)
777     enddo
778    
779     DO I = 0, l
780     DO J = I+2, m
781     PLM(I, J)=((2.0D0*J-1.0D0)*X*PLM(I,J-1) - &
782     (I+J-1.0D0)*PLM(I,J-2))/(J-I)
783     end DO
784     end DO
785 gezelter 1314
786 gezelter 1360 DLM(0, 0)=0.0D0
787    
788     DO J = 1, m
789     DLM(0, J)=LS*J*(PLM(0,J-1)-X*PLM(0,J))/XS
790     end DO
791    
792     DO I = 1, l
793     DO J = I, m
794     DLM(I,J) = LS*I*X*PLM(I, J)/XS + (J+I)*(J-I+1.0D0)/XQ*PLM(I-1, J)
795     end DO
796     end DO
797    
798     RETURN
799     END SUBROUTINE Associated_Legendre
800 gezelter 1314
801    
802 gezelter 1360 subroutine Orthogonal_Polynomial(x, m, function_type, pl, dpl)
803    
804     ! Purpose: Compute orthogonal polynomials: Tn(x) or Un(x),
805     ! or Ln(x) or Hn(x), and their derivatives
806     ! Input : function_type --- Function code
807     ! =1 for Chebyshev polynomial Tn(x)
808     ! =2 for Chebyshev polynomial Un(x)
809     ! =3 for Laguerre polynomial Ln(x)
810     ! =4 for Hermite polynomial Hn(x)
811     ! n --- Order of orthogonal polynomials
812     ! x --- Argument of orthogonal polynomials
813     ! Output: PL(n) --- Tn(x) or Un(x) or Ln(x) or Hn(x)
814     ! DPL(n)--- Tn'(x) or Un'(x) or Ln'(x) or Hn'(x)
815     !
816     ! adapted from the routines in
817     ! COMPUTATION OF SPECIAL FUNCTIONS by Shanjie Zhang and Jianming Jin
818     ! ISBN 0-471-11963-6
819     !
820     ! The original Fortran77 codes can be found here:
821     ! http://iris-lee3.ece.uiuc.edu/~jjin/routines/routines.html
822    
823     real(kind=8), intent(in) :: x
824     integer, intent(in):: m
825     integer, intent(in):: function_type
826     real(kind=8), dimension(0:m), intent(inout) :: pl, dpl
827    
828     real(kind=8) :: a, b, c, y0, y1, dy0, dy1, yn, dyn
829     integer :: k
830 gezelter 1317
831 gezelter 1360 A = 2.0D0
832     B = 0.0D0
833     C = 1.0D0
834     Y0 = 1.0D0
835     Y1 = 2.0D0*X
836     DY0 = 0.0D0
837     DY1 = 2.0D0
838     PL(0) = 1.0D0
839     PL(1) = 2.0D0*X
840     DPL(0) = 0.0D0
841     DPL(1) = 2.0D0
842     IF (function_type.EQ.CHEBYSHEV_TN) THEN
843     Y1 = X
844     DY1 = 1.0D0
845     PL(1) = X
846     DPL(1) = 1.0D0
847     ELSE IF (function_type.EQ.LAGUERRE) THEN
848     Y1 = 1.0D0-X
849     DY1 = -1.0D0
850     PL(1) = 1.0D0-X
851     DPL(1) = -1.0D0
852     ENDIF
853     DO K = 2, m
854     IF (function_type.EQ.LAGUERRE) THEN
855     A = -1.0D0/K
856     B = 2.0D0+A
857     C = 1.0D0+A
858     ELSE IF (function_type.EQ.HERMITE) THEN
859     C = 2.0D0*(K-1.0D0)
860     ENDIF
861     YN = (A*X+B)*Y1-C*Y0
862     DYN = A*Y1+(A*X+B)*DY1-C*DY0
863     PL(K) = YN
864     DPL(K) = DYN
865     Y0 = Y1
866     Y1 = YN
867     DY0 = DY1
868     DY1 = DYN
869     end DO
870     RETURN
871    
872     end subroutine Orthogonal_Polynomial
873    
874 gezelter 1317 end module shapes