SandBox: geteii.f

File geteii.f, 6.3 KB (added by bryans@…, 17 years ago)

Returns EII rate coefficients

Line 
1 subroutine geteii(z_in, ion_in, temp_in, rate)
2
3c================
4c
5c For a given ionisation stage (ion_in) of an element (z_in)
6c this code returns the electron impact ionisation (EII) rate
7c coefficient (rate) at temperature temp_in. EII data comes from
8c Dere, 2007, A&A, 466, 771 and this codes calls a cubic spline
9c routine to return rate at the given temp_in.
10c
11c Inputs:
12c z_in = elements (1-30, i.e., H-Zn)
13c ion_in = charge state of ion AFTER ionisation (1-30)
14c temp_in = temperature at which rate coefficient is desired (K)
15c
16c Outputs:
17c rate = EII rate coefficient at temp_in (cm^-3 s^-1)
18c
19c
20c Paul Bryans
21c Columbia University
22c 16 September 2008
23c
24c================
25
26 implicit none
27
28 real*8 temp(300), eii(300), temp_in, rate
29 real*8 logtemp(300), logeii(300), logtemp_in, logeii_in
30 real*8 d2logeii(300)
31 logical lspl
32 character eiifile*120, element(30)*2
33 integer i, z_in, ion_in, npts
34
35 data(element(i),i=1,30)/'h','he','li','be','b','c','n','o','f',
36 & 'ne','na','mg','al','si','p','s','cl',
37 & 'ar','k','ca','sc','ti','v','cr','mn',
38 & 'fe','co','ni','cu','zn'/
39
40
41
42 logtemp_in=dlog10(temp_in)
43 lspl=.true.
44
45
46 if (ion_in.gt.9) then
47 eiifile='/path to files here/'//
48 & element(z_in)(1:len_trim(element(z_in)))//'_'//
49 & char(mod(ion_in/10,10)+48)//char(mod(ion_in,10)+48)
50 & //'_chianti.ionizdat'
51 else
52 eiifile='/path to files here/'//
53 & element(z_in)(1:len_trim(element(z_in)))//'_'//
54 & char(mod(ion_in,10)+48)//'_chianti.ionizdat'
55 endif
56
57 write(6,*)eiifile
58
59 call read_ionrecdat(eiifile,temp,eii,npts)
60
61
62 if(lspl)then
63
64
65 do i=1,npts
66 logtemp(i)=dlog10(temp(i))
67 logeii(i)=dlog10(eii(i))
68 enddo
69
70 call spline(npts, logtemp, logeii, d2logeii)
71 call spline_int(npts, logtemp, logeii, d2logeii,
72 & logtemp_in, logeii_in)
73
74 else
75
76c linear interpolation not implemented
77
78 endif
79
80 if(logeii_in.eq.0)then
81 rate=0d0
82 else
83 rate =10d0**(logeii_in)
84 endif
85
86
87 return
88
89
90 end
91
92c================
93c================
94
95
96 subroutine read_ionrecdat(file,temp,rate,npts)
97
98c================
99c
100c Returns temperature and rate coefficient values from EII
101c tables of Dere, 2007, A&A, 466, 771.
102c
103c Paul Bryans
104c Columbia University
105c 16 September 2008
106c
107c================
108
109 implicit none
110
111 real*8 temp(300), rate(300)
112 character file*120
113 integer i, npts, iunt12
114 logical open12
115 parameter (iunt12=12)
116
117
118 if (open12) then
119 close(12)
120 open12=.false.
121 endif
122 open( unit=iunt12 , file=file , status='unknown')
123 open12=.true.
124
125 i=0
126 10 continue
127 i=i+1
128 read(iunt12,1000) temp(i), rate(i)
129 if(temp(i).gt.0) goto 10
130
131 npts=i-1
132
133 return
134
135 1000 format(2e12.3)
136
137 end
138
139c================
140c================
141
142
143 subroutine spline(npts, xin, yin, d2y)
144
145c================
146c
147c For an array of xin and yin values, this routine
148c calculates the second derivatives of y (d2y) for
149c cubic spline interpolation with d2y set to zero
150c at both end points.
151c
152c Paul Bryans
153c Columbia University
154c 16 September 2008
155c
156c================
157
158
159 implicit none
160
161 integer npts, i, nmax
162 parameter (nmax=300)
163 real*8 xin(nmax), yin(nmax), d2y(nmax)
164 real*8 a(nmax), b(nmax), c(nmax), d(nmax)
165 real*8 bb, tmp(nmax)
166
167
168c================
169c
170c natural cubic spline with second derivatives at end points set to zero
171c
172c================
173
174 d2y(1) = 0d0
175 d2y(npts) = 0d0
176
177
178c================
179c
180c put tridiagonal system of second derivatives in the form,
181c a(i)*d2y(i-1) + b(i)*d2y(i) + c(i)*d2y(i+1) = d(i)
182c
183c================
184
185
186 do i=2,npts-1
187 a(i) = (xin(i)-xin(i-1))/6d0
188 b(i) = (xin(i+1)-xin(i-1))/3d0
189 c(i) = (xin(i+1)-xin(i))/6d0
190 d(i) = (yin(i+1)-yin(i))/(xin(i+1)-xin(i)) -
191 & (yin(i)-yin(i-1))/(xin(i)-xin(i-1))
192 enddo
193
194
195
196c================
197c
198c forward substitution of the tridiagonal system
199c
200c================
201
202 bb = b(2)
203 d2y(2) = d(2)/bb
204 do i=3,npts-1
205 tmp(i) = c(i-1)/bb
206 bb = b(i) - a(i)*tmp(i)
207 d2y(i) = (d(i)-a(i)*d2y(i-1))/bb
208 enddo
209
210
211c================
212c
213c backward substitution of the tridiagonal system
214c
215c================
216
217 do i=npts-2,2,-1
218 d2y(i)=d2y(i)-c(i)*d2y(i+1)
219 enddo
220
221 return
222
223 end
224
225
226
227
228c================
229c================
230
231 subroutine spline_int(npts, xin, yin, d2y, xout, yout)
232
233c================
234c
235c For an array of xin and yin values, d2y is the
236c second derivative of yin calculated by spline
237c routine. This routine returns yout for a given
238c xout by interpolating.
239c
240c Paul Bryans
241c Columbia University
242c 16 September 2008
243c
244c================
245
246
247 implicit none
248
249 integer npts, i, index, nmax
250 parameter (nmax=300)
251 real*8 xin(nmax), yin(nmax), xout, yout
252 real*8 d2y(nmax), a, b, c, d
253
254
255c================
256c
257c extrapolation
258c
259c================
260
261 if (xout.lt.xin(1)) then
262 write(6,*) 'warning: extrapolation '
263 index=1
264 a=1d0
265 b=0d0
266 c=xout-xin(1)
267 d=0d0
268 elseif (xout.gt.xin(npts)) then
269 write(6,*) 'warning: extrapolation '
270 index=npts-1
271 a=0d0
272 b=1d0
273 c=0d0
274 d=xout-xin(npts)
275
276
277c================
278c
279c find position of xout in xin array for interpolation
280c
281c================
282
283 else
284 do i=npts,2,-1
285 if(xout.le.xin(i)) index=i-1
286 enddo
287
288
289c================
290c
291c set up interpolation parameters,
292c yout = a*yin(i) + b*yin(i+1) + c*d2y(i) + c*d2y(i+1)
293c
294c================
295
296 a = (xin(index+1)-xout)/(xin(index+1)-xin(index))
297 b = 1d0-a
298 c = ((a**3d0-a)*(xin(index+1)-xin(index))**2d0)/6d0
299 d = ((b**3d0-b)*(xin(index+1)-xin(index))**2d0)/6d0
300
301 endif
302
303 yout = a*yin(index) + b*yin(index+1) + c*d2y(index)
304 & + d*d2y(index+1)
305
306
307 return
308
309 end
310