MPI-AMRVAC  3.0
The MPI - Adaptive Mesh Refinement - Versatile Advection Code
mod_opal_opacity.t
Go to the documentation of this file.
1 !> This module reads in opacities from opal tables.
2 
4  implicit NONE
5 
6  !> min and max indices for R,T-range in opacity table
7  integer, parameter :: rmin = 2
8  integer, parameter :: rmax = 20
9  integer, parameter :: tmin = 7
10  integer, parameter :: tmax = 76
11 
12  !> The opacity tables are read once and stored globally in Kappa_vals
13  double precision, public :: kappa_vals(7:76,2:20)
14  double precision, public :: kappa_vals1(7:76,2:20)
15  double precision, public :: kappa_vals2(7:76,2:20)
16 
17  double precision, public :: log_r_list(2:20)
18  double precision, public :: log_t_list(7:76)
19 
20  character(255), public :: amrvac_dir
21  character(255), public :: fileplace
22  ! character(*), parameter, public :: AMRVAC_DIR = "/STER/luka/codes/Nico_amrvac/" ! use call getenv("AMRVAC_DIR", AMRVAC_DIR)
23  ! character(*), parameter, public :: fileplace = AMRVAC_DIR//"src/rhd/Opacity_tables/"
24 
25  ! character(len=:), allocatable :: AMRVAC_DIR != "/STER/luka/codes/Nico_amrvac" ! use call getenv("AMRVAC_DIR", AMRVAC_DIR)
26  ! character, allocatable :: fileplace != AMRVAC_DIR//"src/rhd/Opacity_tables/"
27 
28 
29  public :: init_opal
30  public :: set_opal_opacity
31 
32  contains
33 
34 !> This routine is called when the fld radiation module is initialised.
35 !> Here, the tables for different He Abndcs are read and interpolated
36 subroutine init_opal(He_abundance,tablename)
37  ! use mod_global_parameters
38 
39  double precision, intent(in) :: he_abundance
40  character(6), intent(in) :: tablename
41 
42  !> Y1 actually 1.0, NOT 0.1???
43  double precision :: y1 = 0.1000
44  double precision :: y2 = 0.0999
45 
46 
47  CALL get_environment_variable("AMRVAC_DIR", amrvac_dir)
48  fileplace = trim(amrvac_dir)//"/src/rhd/Opacity_tables/"
49 
50 
51  ! character(len=std_len) :: DIR_tmp
52  ! character(len=std_len) :: FILE_tmp
53  !
54  !
55  ! call GET_ENVIRONMENT_VARIABLE("AMRVAC_DIR", DIR_tmp)
56  ! ! allocate(AMRVAC_DIR(len=len_trim(DIR_tmp)))
57  ! print*, DIR_tmp
58  ! print*, TRIM(DIR_tmp)
59  !
60  ! allocate(character(len=len_trim(DIR_tmp)) :: AMRVAC_DIR)
61  !
62  ! print*, AMRVAC_DIR
63  !
64  ! FILE_tmp = AMRVAC_DIR//"src/rhd/Opacity_tables/"
65  ! print*, FILE_tmp
66  ! ! allocate(fileplace(len=len_trim(FILE_tmp)))
67  ! fileplace = trim(FILE_tmp)
68  !
69  ! print*, '---',fileplace,'---'
70  ! stop
71 
72  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
73 
74  ! if (Y1 .gt. Y2) then
75  ! if (He_abundance .gt. Y1) call mpistop('OPAL table not covered')
76  ! if (He_abundance .lt. Y2) call mpistop('OPAL table not covered')
77  ! else
78  ! if (He_abundance .lt. Y1) call mpistop('OPAL table not covered')
79  ! if (He_abundance .gt. Y2) call mpistop('OPAL table not covered')
80  ! endif
81 
82  !> WR
83  ! call read_table(Log_R_list, Log_T_list, Kappa_vals1,'Y09800')
84 
85  !> RSG
86  ! call read_table(Log_R_list, Log_T_list, Kappa_vals1,'Y00999')
87 
88  !> General
90 
91  ! call read_table(Log_R_list, Log_T_list, Kappa_vals1,'Y01000')
92  ! call read_table(Log_R_list, Log_T_list, Kappa_vals2,'Y00999')
93 
94  ! if (He_abundance .eq. Y1) then
95  ! Kappa_vals = Kappa_vals1
96  ! print*, 'Using correct table'
97  ! stop
98  ! elseif (He_abundance .eq. Y2) then
99  ! Kappa_vals = Kappa_vals2
100  ! else
101  ! call interpolate_two_tables(Y1,Y2, He_abundance, Kappa_vals1, Kappa_vals2, Kappa_vals)
102  ! endif
103 
105 
106 end subroutine init_opal
107 
108 !> This subroutine calculates the opacity for
109 !> a given temperature-density structure.
110 !> The opacities are read from a table that has the initialised metalicity
111 subroutine set_opal_opacity(rho,temp,kappa)
112  double precision, intent(in) :: rho, temp
113  double precision, intent(out) :: kappa
114 
115  double precision :: r_input, t_input, k_output
116 
117  r_input = rho/(temp*1d-6)**3
118  t_input = temp
119 
120  r_input = dlog10(r_input)
121  t_input = dlog10(t_input)
122 
123  call get_kappa(kappa_vals, log_r_list, log_t_list, r_input, t_input, k_output)
124 
125  !> If the outcome is 9.999, look right in the table
126  do while (k_output .gt. 9.0d0)
127  ! print*, 'R,T datapoint out of opal table'
128  r_input = r_input + 0.5
129  call get_kappa(kappa_vals, log_r_list, log_t_list, r_input, t_input, k_output)
130  enddo
131 
132  !> If the outcome is NaN, look left in the table
133  do while (k_output .eq. 0.0d0)
134  ! print*, 'R,T datapoint out of opal table'
135  r_input = r_input - 0.5d0
136  call get_kappa(kappa_vals, log_r_list, log_t_list, r_input, t_input, k_output)
137  enddo
138 
139  kappa = 10d0**k_output
140 
141 end subroutine set_opal_opacity
142 
143 !> This routine reads out values and arguments from an opacity table
144 subroutine read_table(R, T, K, filename)
145  !> This routine reads in the the values for log kappa, and the values for log T and log R on the x and y axis
146 
147  double precision, intent(out) :: K(7:76,2:20), R(2:20), T(7:76)
148  character(*), intent(in) :: filename
149 
150  character :: dum
151  integer :: row, col
152 
153  OPEN(1,status = 'old', file=trim(fileplace)//filename)
154 
155  !> Skip first 4 lines
156  do row = 1,4
157  READ(1,*)
158  enddo
159 
160  !> Read R
161  READ(1,*) dum,r(2:20)
162 
163  READ(1,*)
164 
165  !> Read T and K
166  do row = 7,76 !> NOT READING ENTIRE TABLE
167  READ(1,'(f4.2,19f7.3)') t(row), k(row,2:20)
168  enddo
169 
170  CLOSE(1)
171 
172 end subroutine read_table
173 
174 
175 !> This subroutine creates a new table for a given He abundance,
176 ! by interpolating to known tables at every point in the R,T plane
177 subroutine interpolate_two_tables(Y1, Y2, Y_in, K1, K2, K_interp)
178 
179  double precision, intent(in) :: K1(7:76,2:20), K2(7:76,2:20)
180  double precision, intent(in) :: Y1, Y2, Y_in
181  double precision, intent(out) :: K_interp(7:76,2:20)
182 
183  integer row, colum
184 
185  do colum=2,20
186  do row=7,76
187  call interpolate1d(y1,y2,y_in,k1(row,colum),k2(row,colum),k_interp(row,colum))
188  enddo
189  enddo
190 
191 end subroutine interpolate_two_tables
192 
193 
194 !>This subroutine looks in the table for the four couples (T,R)
195 !surrounding a given input for T and R
196 subroutine get_kappa(Kappa_vals, Log_R_list, Log_T_list, R, T, K)
197 
198  double precision, intent(in) :: Kappa_vals(7:76,2:20)
199  double precision, intent(in) :: Log_R_list(2:20)
200  double precision, intent(in) :: Log_T_list(7:76)
201 
202  double precision, intent(in) :: R, T
203  double precision, intent(out) :: K
204 
205  integer :: low_r_index, up_r_index
206  integer :: low_t_index, up_t_index
207 
208  if (r .gt. maxval(log_r_list)) then
209  ! print*, 'Extrapolating in logR'
210  low_r_index = 19
211  up_r_index = 20
212  elseif (r .lt. minval(log_r_list)) then
213  ! print*, 'Extrapolating in logR'
214  low_r_index = 2
215  up_r_index = 3
216  else
217  call get_low_up_index(r, log_r_list, 2, 20, low_r_index, up_r_index)
218  endif
219 
220  if (t .gt. maxval(log_t_list)) then
221  ! print*, 'Extrapolating in logT'
222  low_t_index = 75
223  up_t_index = 76
224  elseif ( t .lt. minval(log_t_list)) then
225  ! print*, 'Extrapolating in logT'
226  low_t_index = 7
227  up_t_index = 8
228  else
229  call get_low_up_index(t, log_t_list, 7, 76, low_t_index, up_t_index)
230  endif
231 
232  call interpolate_krt(low_r_index, up_r_index, low_t_index, up_t_index, log_r_list, log_t_list, kappa_vals, r, t, k)
233 
234 end subroutine get_kappa
235 
236 
237 !> this subroutine finds the indexes in R and T arrays of the two values surrounding the input R and T
238 subroutine get_low_up_index(x, x_list, imin, imax, low_i, up_i)
239 
240  integer, intent(in) :: imin, imax
241  double precision, intent(in) :: x
242  double precision, intent(in) :: x_list(imin:imax)
243 
244  integer, intent(out) :: low_i, up_i
245 
246  double precision :: low_val, up_val
247  double precision :: res(imin:imax)
248 
249  res = x_list - x
250 
251  up_val = minval(res, mask = res .ge. 0) + x
252  low_val = maxval(res, mask = res .le. 0) + x
253 
254  up_i = minloc(abs(x_list - up_val),1) + imin -1
255  low_i = minloc(abs(x_list - low_val),1) + imin -1
256 
257 
258  if (up_i .eq. low_i) low_i = low_i - 1
259 
260 end subroutine get_low_up_index
261 
262 !> This subroutine does a bilinear interpolation in the R,T-plane
263 subroutine interpolate_krt(low_r, up_r, low_t, up_t, Log_R_list, Log_T_list, Kappa_vals, R, T, k_interp)
264 
265  integer, intent(in) :: low_r, up_r, low_t, up_t
266  double precision, intent(in) :: Kappa_vals(7:76,2:20)
267  double precision, intent(in) :: Log_R_list(2:20)
268  double precision, intent(in) :: Log_T_list(7:76)
269  double precision, intent(in) :: R,T
270  double precision, intent(out) :: k_interp
271 
272  double precision :: r1,r2,t1,t2
273  double precision :: k1, k2, k3, k4
274  double precision :: ka, kb
275 
276  !Cool ascii drawing of interpolation scheme: first interpolate twice in the T coord to get
277  !ka and kb, then interpolate in the R coord to get ki
278 
279 ! r_1 R r_2
280 ! | |
281 ! | |
282 ! ----k1--------ka-----k2----- t_1
283 ! | | |
284 ! | | |
285 ! T | | |
286 ! | | |
287 ! | ki |
288 ! | | |
289 ! ----k3--------kb-----k4----- t_2
290 ! | |
291 ! | |
292 
293 
294  r1 = log_r_list(low_r)
295  r2 = log_r_list(up_r)
296  t1 = log_t_list(low_t)
297  t2 = log_t_list(up_t)
298 
299  k1 = kappa_vals(low_t, low_r)
300  k2 = kappa_vals(low_t, up_r)
301  k3 = kappa_vals(up_t, low_r)
302  k4 = kappa_vals(up_t, up_r)
303 
304  call interpolate1d(r1,r2,r,k1,k2,ka)
305  call interpolate1d(r1,r2,r,k3,k4,kb)
306  call interpolate1d(t1,t2,t,ka,kb,k_interp)
307 
308 end subroutine interpolate_krt
309 
310 
311 !> Interpolation in one dimension
312 subroutine interpolate1d(x1, x2, x, y1, y2, y)
313 
314  double precision, intent(in) :: x, x1, x2
315  double precision, intent(in) :: y1, y2
316  double precision, intent(out) :: y
317 
318  y = y1 + (x-x1)*(y2-y1)/(x2-x1)
319 
320 end subroutine interpolate1d
321 
322 end module mod_opal_opacity
323 
324 !> Interpolation on logarithmic scale
325 subroutine log_interpolate1d(x1, x2, x, y1, y2, y)
326 
327  double precision, intent(in) :: x, x1, x2
328  double precision, intent(in) :: y1, y2
329  double precision, intent(out) :: y
330 
331  double precision :: expx, expx1, expx2
332  double precision :: expy1, expy2
333 
334  expx = 10**x
335  expx1 = 10**x1
336  expx2 = 10**x2
337 
338  expy1 = 10**y1
339  expy2 = 10**y2
340 
341  y = expy1 + (expx-expx1)*(expy2-expy1)/(expx2-expx1)
342  y = log10(y)
343 
344 end subroutine log_interpolate1d
subroutine log_interpolate1d(x1, x2, x, y1, y2, y)
Interpolation on logarithmic scale.
This module reads in opacities from opal tables.
double precision, dimension(2:20), public log_r_list
subroutine get_kappa(Kappa_vals, Log_R_list, Log_T_list, R, T, K)
This subroutine looks in the table for the four couples (T,R)
integer, parameter rmin
min and max indices for R,T-range in opacity table
double precision, dimension(7:76, 2:20), public kappa_vals
The opacity tables are read once and stored globally in Kappa_vals.
subroutine interpolate_two_tables(Y1, Y2, Y_in, K1, K2, K_interp)
This subroutine creates a new table for a given He abundance,.
integer, parameter tmax
subroutine get_low_up_index(x, x_list, imin, imax, low_i, up_i)
this subroutine finds the indexes in R and T arrays of the two values surrounding the input R and T
subroutine interpolate_krt(low_r, up_r, low_t, up_t, Log_R_list, Log_T_list, Kappa_vals, R, T, k_interp)
This subroutine does a bilinear interpolation in the R,T-plane.
character(255), public fileplace
double precision, dimension(7:76, 2:20), public kappa_vals2
integer, parameter rmax
double precision, dimension(7:76), public log_t_list
subroutine, public set_opal_opacity(rho, temp, kappa)
This subroutine calculates the opacity for a given temperature-density structure. The opacities are r...
integer, parameter tmin
subroutine interpolate1d(x1, x2, x, y1, y2, y)
Interpolation in one dimension.
double precision, dimension(7:76, 2:20), public kappa_vals1
subroutine, public init_opal(He_abundance, tablename)
This routine is called when the fld radiation module is initialised. Here, the tables for different H...
character(255), public amrvac_dir
subroutine read_table(R, T, K, filename)
This routine reads out values and arguments from an opacity table.