ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/OpenMD/trunk/src/UseTheForce/DarkSide/switcheroo.F90
Revision: 937
Committed: Sun Apr 16 02:51:16 2006 UTC (19 years, 3 months ago) by chrisfen
File size: 7262 byte(s)
Log Message:
added a cubic spline to switcheroo

File Contents

# Content
1 !!
2 !! Copyright (c) 2005 The University of Notre Dame. All Rights Reserved.
3 !!
4 !! The University of Notre Dame grants you ("Licensee") a
5 !! non-exclusive, royalty free, license to use, modify and
6 !! redistribute this software in source and binary code form, provided
7 !! that the following conditions are met:
8 !!
9 !! 1. Acknowledgement of the program authors must be made in any
10 !! publication of scientific results based in part on use of the
11 !! program. An acceptable form of acknowledgement is citation of
12 !! the article in which the program was described (Matthew
13 !! A. Meineke, Charles F. Vardeman II, Teng Lin, Christopher
14 !! J. Fennell and J. Daniel Gezelter, "OOPSE: An Object-Oriented
15 !! Parallel Simulation Engine for Molecular Dynamics,"
16 !! J. Comput. Chem. 26, pp. 252-271 (2005))
17 !!
18 !! 2. Redistributions of source code must retain the above copyright
19 !! notice, this list of conditions and the following disclaimer.
20 !!
21 !! 3. Redistributions in binary form must reproduce the above copyright
22 !! notice, this list of conditions and the following disclaimer in the
23 !! documentation and/or other materials provided with the
24 !! distribution.
25 !!
26 !! This software is provided "AS IS," without a warranty of any
27 !! kind. All express or implied conditions, representations and
28 !! warranties, including any implied warranty of merchantability,
29 !! fitness for a particular purpose or non-infringement, are hereby
30 !! excluded. The University of Notre Dame and its licensors shall not
31 !! be liable for any damages suffered by licensee as a result of
32 !! using, modifying or distributing the software or its
33 !! derivatives. In no event will the University of Notre Dame or its
34 !! licensors be liable for any lost revenue, profit or data, or for
35 !! direct, indirect, special, consequential, incidental or punitive
36 !! damages, however caused and regardless of the theory of liability,
37 !! arising out of the use of or inability to use software, even if the
38 !! University of Notre Dame has been advised of the possibility of
39 !! such damages.
40 !!
41
42 module switcheroo
43
44 use definitions
45 use interpolation
46
47 implicit none
48 PRIVATE
49
50 #define __FORTRAN90
51 #include "UseTheForce/fSwitchingFunction.h"
52 #include "UseTheForce/DarkSide/fSwitchingFunctionType.h"
53
54 real ( kind = dp ), dimension(NSWITCHTYPES) :: rin
55 real ( kind = dp ), dimension(NSWITCHTYPES) :: rout
56 real ( kind = dp ), dimension(NSWITCHTYPES) :: rin2
57 real ( kind = dp ), dimension(NSWITCHTYPES) :: rout2
58 real ( kind = dp ), save :: c0, c1, c2, c3, c4, c5
59
60 logical, dimension(NSWITCHTYPES) :: isOK
61 logical, save :: haveFunctionType = .false.
62 logical, save :: haveSqrtSpline = .false.
63 logical, save :: useSpline = .true.
64 integer, save :: functionType = CUBIC
65
66
67 ! spline variables
68 type(cubicSpline), save :: scoef
69 real ( kind = dp ), dimension(SPLINE_SEGMENTS) :: xValues
70 real ( kind = dp ), dimension(SPLINE_SEGMENTS) :: yValues
71 real ( kind = dp ), save :: dSqrt1, dSqrtN, range, dX
72 real ( kind = dp ), save :: lowerBound
73 logical, save :: uniformSpline = .true.
74
75 public::set_switch
76 public::set_function_type
77 public::get_switch
78
79 contains
80
81 subroutine set_switch(SwitchType, rinner, router)
82
83 real ( kind = dp ), intent(in):: rinner, router
84 integer, intent(in) :: SwitchType
85 integer :: i
86
87 if (SwitchType .gt. NSWITCHTYPES) then
88 write(default_error, *) &
89 'set_switch: not that many switch types! '
90 return
91 endif
92
93 isOK(SwitchType) = .false.
94
95 if (router .lt. rinner) then
96 write(default_error, *) &
97 'set_switch: router is less than rinner '
98 return
99 endif
100
101 if ((router .lt. 0.0d0) .or. (rinner .lt. 0.0d0)) then
102 write(default_error, *) &
103 'set_switch: one of the switches is negative!'
104 return
105 endif
106
107 rin(SwitchType) = rinner
108 rout(SwitchType) = router
109 rin2(SwitchType) = rinner * rinner
110 rout2(SwitchType) = router * router
111 isOK(SwitchType) = .true.
112
113 if (.not.haveSqrtSpline) then
114 ! fill arrays for building the spline
115 lowerBound = 1.0d0 ! the smallest value expected for r2
116 range = rout2(SwitchType) - lowerBound
117 dX = range / (SPLINE_SEGMENTS - 1)
118
119 ! the spline is bracketed by lowerBound and rout2 endpoints
120 xValues(1) = lowerBound
121 yValues(1) = dsqrt(lowerBound)
122 do i = 1, SPLINE_SEGMENTS-1
123 xValues(i+1) = i * dX
124 yValues(i+1) = dsqrt( i * dX )
125 enddo
126
127 ! set the endpoint derivatives
128 dSqrt1 = 1 / ( 2.0d0 * dsqrt( xValues(1) ) )
129 dSqrtN = 1 / ( 2.0d0 * dsqrt( xValues(SPLINE_SEGMENTS) ) )
130
131 ! call newSpline to fill the coefficient array
132 call newSpline(scoef, xValues, yValues, dSqrt1, dSqrtN, uniformSpline)
133
134 endif
135
136 end subroutine set_switch
137
138 subroutine set_function_type(functionForm)
139 integer, intent(in) :: functionForm
140 functionType = functionForm
141
142 if (functionType .eq. FIFTH_ORDER_POLY) then
143 c0 = 1.0d0
144 c1 = 0.0d0
145 c2 = 0.0d0
146 c3 = -10.0d0
147 c4 = 15.0d0
148 c5 = -6.0d0
149 endif
150 end subroutine set_function_type
151
152 subroutine get_switch(r2, sw, dswdr, r, SwitchType, in_switching_region)
153
154 real( kind = dp ), intent(in) :: r2
155 real( kind = dp ), intent(inout) :: sw, dswdr, r
156 real( kind = dp ) :: ron, roff
157 real( kind = dp ) :: rval, rval2, rval3, rval4, rval5
158 real( kind = dp ) :: rvaldi, rvaldi2, rvaldi3, rvaldi4, rvaldi5
159 integer, intent(in) :: SwitchType
160 logical, intent(inout) :: in_switching_region
161
162 sw = 0.0d0
163 dswdr = 0.0d0
164 in_switching_region = .false.
165
166 if (.not.isOK(SwitchType)) then
167 write(default_error, *) &
168 'get_switch: this switching function has not been set up!'
169 return
170 endif
171
172 if (r2.lt.rout2(SwitchType)) then
173 if (r2.lt.rin2(SwitchType)) then
174
175 sw = 1.0d0
176 dswdr = 0.0d0
177 return
178
179 else
180 if (useSpline) then
181 call lookup_uniform_spline(scoef, r2, r)
182 else
183 r = dsqrt(r2)
184 endif
185
186 ron = rin(SwitchType)
187 roff = rout(SwitchType)
188
189 if (functionType .eq. FIFTH_ORDER_POLY) then
190 rval = ( r - ron )
191 rval2 = rval*rval
192 rval3 = rval2*rval
193 rval4 = rval2*rval2
194 rval5 = rval3*rval2
195 rvaldi = 1.0d0/( roff - ron )
196 rvaldi2 = rvaldi*rvaldi
197 rvaldi3 = rvaldi2*rvaldi
198 rvaldi4 = rvaldi2*rvaldi2
199 rvaldi5 = rvaldi3*rvaldi2
200 sw = c0 + c1*rval*rvaldi + c2*rval2*rvaldi2 + c3*rval3*rvaldi3 &
201 + c4*rval4*rvaldi4 + c5*rval5*rvaldi5
202 dswdr = c1*rvaldi + 2.0d0*c2*rval*rvaldi2 &
203 + 3.0d0*c3*rval2*rvaldi3 + 4.0d0*c4*rval3*rvaldi4 &
204 + 5.0d0*c5*rval4*rvaldi5
205
206 else
207 sw = (roff + 2.0d0*r - 3.0d0*ron)*(roff-r)**2/ ((roff-ron)**3)
208 dswdr = 6.0d0*(r*r - r*ron - r*roff +roff*ron)/((roff-ron)**3)
209
210 endif
211 in_switching_region = .true.
212 return
213 endif
214 else
215 return
216 endif
217
218 end subroutine get_switch
219
220 end module switcheroo