ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/SHAPES/calc_shapes.f90
(Generate patch)

Comparing trunk/SHAPES/calc_shapes.f90 (file contents):
Revision 1317 by gezelter, Tue Jun 29 03:05:57 2004 UTC vs.
Revision 1360 by gezelter, Tue Jul 20 20:02:15 2004 UTC

# Line 1 | Line 1 | module shapes
1   module shapes
2 +
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    implicit none
3  PRIVATE
13  
14 +  PRIVATE
15 +  
16    INTEGER, PARAMETER:: CHEBYSHEV_TN = 1
17    INTEGER, PARAMETER:: CHEBYSHEV_UN = 2
18    INTEGER, PARAMETER:: LAGUERRE     = 3
19    INTEGER, PARAMETER:: HERMITE      = 4
20 +  logical, save :: haveShapeMap = .false.
21  
22 < contains  
22 >  public :: do_shape_pair
23  
24 < SUBROUTINE Get_Associated_Legendre(x, l, m, lmax, plm, dlm)
25 <  
26 <  ! Purpose: Compute the associated Legendre functions
27 <  !          Plm(x) and their derivatives Plm'(x)
28 <  ! Input :  x  --- Argument of Plm(x)
29 <  !          l  --- Order of Plm(x),  l = 0,1,2,...,n
30 <  !          m  --- Degree of Plm(x), m = 0,1,2,...,N
31 <  !          lmax --- Physical dimension of PLM and DLM
32 <  ! Output:  PLM(l,m) --- Plm(x)
33 <  !          DLM(l,m) --- Plm'(x)
24 >  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  
42 <  real (kind=8), intent(in) :: x
24 <  integer, intent(in) :: lmax, l, m
25 <  real (kind=8), dimension(0:MM,0:N), intent(inout) :: PLM(0:lmax, 0:m)
26 <  real (kind=8), dimension(0:MM,0:N), intent(inout) :: DLM(0:lmax, 0:m)
27 <  integer :: i, j
28 <  real (kind=8) :: xq, xs
29 <  integer :: ls
42 >  type(ShapeList), dimension(:),allocatable :: ShapeMap
43  
31  ! zero out both arrays:
32  DO I = 0, m
33     DO J = 0, l
34        PLM(J,I) = 0.0D0
35        DLM(J,I) = 0.0D0
36     end DO
37  end DO
44  
45 <  ! start with 0,0:
40 <  PLM(0,0) = 1.0D0
45 > contains  
46    
47 <  ! x = +/- 1 functions are easy:
48 <  IF (abs(X).EQ.1.0D0) THEN
49 <     DO I = 1, m
50 <        PLM(0, I) = X**I
51 <        DLM(0, I) = 0.5D0*I*(I+1.0D0)*X**(I+1)
52 <     end DO
53 <     DO J = 1, m
54 <        DO I = 1, l
55 <           IF (I.EQ.1) THEN
56 <              DLM(I, J) = 1.0D+300
57 <           ELSE IF (I.EQ.2) THEN
58 <              DLM(I, J) = -0.25D0*(J+2)*(J+1)*J*(J-1)*X**(J+1)
59 <           ENDIF
60 <        end DO
61 <     end DO
62 <     RETURN
63 <  ENDIF
47 >  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  
68 <  LS = 1
69 <  IF (abs(X).GT.1.0D0) LS = -1
70 <  XQ = sqrt(LS*(1.0D0-X*X))
71 <  XS = LS*(1.0D0-X*X)
68 >    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  
92 <  DO I = 1, l
93 <     PLM(I, I) = -LS*(2.0D0*I-1.0D0)*XQ*PLM(I-1, I-1)
94 <  enddo
95 <  
96 <  DO I = 0, l
97 <     PLM(I, I+1)=(2.0D0*I+1.0D0)*X*PLM(I, I)
98 <  enddo
99 <  
100 <  DO I = 0, l
101 <     DO J = I+2, m
102 <        PLM(I, J)=((2.0D0*J-1.0D0)*X*PLM(I,J-1) - (I+J-1.0D0)*PLM(I,J-2))/(J-I)
103 <     end DO
104 <  end DO
105 <  
106 <  DLM(0, 0)=0.0D0
92 > #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  
141 <  DO J = 1, m
142 <     DLM(0, J)=LS*J*(PLM(0,J-1)-X*PLM(0,J))/XS
83 <  end DO
84 <  
85 <  DO I = 1, l
86 <     DO J = I, m
87 <        DLM(I,J) = LS*I*X*PLM(I, J)/XS + (J+I)*(J-I+1.0D0)/XQ*PLM(I-1, J)
88 <     end DO
89 <  end DO
141 >       call Associated_Legendre(cti, ShapeMap(me1)%bigL, &
142 >            ShapeMap(me1)%bigM, lmax, plm_i, dlm_i)
143  
144 <  RETURN
145 < END SUBROUTINE Get_Associated_Legendre
144 >       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  
286 +    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  
432 < subroutine Get_Orthogonal_Polynomial(x, m, function_type, pl, dpl)
432 >          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  
502 <  ! Purpose: Compute orthogonal polynomials: Tn(x) or Un(x),
503 <  !          or Ln(x) or Hn(x), and their derivatives
504 <  ! Input :  function_type --- Function code
505 <  !                 =1 for Chebyshev polynomial Tn(x)
506 <  !                 =2 for Chebyshev polynomial Un(x)
507 <  !                 =3 for Laguerre polynomial Ln(x)
508 <  !                 =4 for Hermite polynomial Hn(x)
509 <  !          n ---  Order of orthogonal polynomials
510 <  !          x ---  Argument of orthogonal polynomials
511 <  ! Output:  PL(n) --- Tn(x) or Un(x) or Ln(x) or Hn(x)
512 <  !          DPL(n)--- Tn'(x) or Un'(x) or Ln'(x) or Hn'(x)
502 >    ! 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    
748 <  real(kind=8), intent(in) :: x
749 <  integer, intent(in):: m
750 <  integer, intent(in):: function_type
751 <  real(kind=8), dimension(0:m), intent(inout) :: pl, dpl
748 >    ! 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    
786 <  real(kind=8) :: a, b, c, y0, y1, dy0, dy1, yn, dyn
787 <  integer :: k
786 >    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  
117  A = 2.0D0
118  B = 0.0D0
119  C = 1.0D0
120  Y0 = 1.0D0
121  Y1 = 2.0D0*X
122  DY0 = 0.0D0
123  DY1 = 2.0D0
124  PL(0) = 1.0D0
125  PL(1) = 2.0D0*X
126  DPL(0) = 0.0D0
127  DPL(1) = 2.0D0
128  IF (function_type.EQ.CHEBYSHEV_TN) THEN
129     Y1 = X
130     DY1 = 1.0D0
131     PL(1) = X
132     DPL(1) = 1.0D0
133  ELSE IF (function_type.EQ.LAGUERRE) THEN
134     Y1 = 1.0D0-X
135     DY1 = -1.0D0
136     PL(1) = 1.0D0-X
137     DPL(1) = -1.0D0
138  ENDIF
139  DO K = 2, m
140     IF (function_type.EQ.LAGUERRE) THEN
141        A = -1.0D0/K
142        B = 2.0D0+A
143        C = 1.0D0+A
144     ELSE IF (function_type.EQ.HERMITE) THEN
145        C = 2.0D0*(K-1.0D0)
146     ENDIF
147     YN = (A*X+B)*Y1-C*Y0
148     DYN = A*Y1+(A*X+B)*DY1-C*DY0
149     PL(K) = YN
150     DPL(K) = DYN
151     Y0 = Y1
152     Y1 = YN
153     DY0 = DY1
154     DY1 = DYN
155  end DO
156  RETURN
801  
802 < end subroutine Get_Orthogonal_Polynomial
802 >  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  
831 +    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   end module shapes

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines