MPI-AMRVAC  3.0
The MPI - Adaptive Mesh Refinement - Versatile Advection Code
mod_cak_opacity.t
Go to the documentation of this file.
2  implicit NONE
3 
4  !> min and max indices for R,T-range in opacity table
5  integer, parameter :: dmin = 2
6  integer, parameter :: dmax = 21
7  integer, parameter :: tmin = 2
8  integer, parameter :: tmax = 21
9 
10  !> The opacity tables are read once and stored globally in Kappa_vals
11  double precision, public :: alpha_vals(dmin:dmax,tmin:tmax)
12  double precision, public :: qbar_vals(dmin:dmax,tmin:tmax)
13  double precision, public :: q0_vals(dmin:dmax,tmin:tmax)
14  double precision, public :: kappa_e_vals(dmin:dmax,tmin:tmax)
15 
16  double precision, public :: log_d_list(dmin:dmax)
17  double precision, public :: log_t_list(tmin:tmax)
18 
19  character(255), public :: amrvac_dir
20  character(255), public :: fileplace
21 
22  public :: init_cak
23  public :: set_cak_opacity
24 
25  contains
26 
27 !> This routine is called when the fld radiation module is initialised.
28 !> Here, the tables for different He Abndcs are read and interpolated
29 subroutine init_cak(tablename)
30  ! use mod_global_parameters
31  character(6), intent(in) :: tablename
32 
33  CALL get_environment_variable("AMRVAC_DIR", amrvac_dir)
34  fileplace = trim(amrvac_dir)//"/src/rhd/CAK_tables/"
35 
36  call read_table(log_d_list, log_t_list, alpha_vals, trim(tablename)//"/al_TD")
37  call read_table(log_d_list, log_t_list, qbar_vals, trim(tablename)//"/Qb_TD")
38  call read_table(log_d_list, log_t_list, q0_vals, trim(tablename)//"/Q0_TD")
39  call read_table(log_d_list, log_t_list, kappa_e_vals, trim(tablename)//"/Ke_TD")
40 
41  ! print*, "Read Luka's tables"
42 
43 end subroutine init_cak
44 
45 !> This subroutine calculates the opacity for
46 !> a given temperature-density structure.
47 !> The opacities are read from a table that has the initialised metalicity
48 subroutine set_cak_opacity(rho,temp, gradv,alpha_output, Qbar_output, Q0_output, kappa_e_output)
49  double precision, intent(in) :: rho, temp, gradv
50  double precision, intent(out) :: alpha_output, qbar_output, q0_output, kappa_e_output
51 
52  double precision, PARAMETER :: const_c = 2.99792458d10 ! cm S^-1 ; Speed of light
53 
54  double precision :: d_input, t_input
55 
56  double precision :: kappa_cak
57  double precision :: tau, m_t
58 
59  d_input = dlog10(rho)
60  t_input = dlog10(temp)
61 
62  d_input = min(-7.d0-1.d-5, d_input)
63  d_input = max(-16.d0+1.d-5, d_input)
64  t_input = min(5d0-1.d-5, t_input)
65  t_input = max(4d0+1.d-5, t_input)
66 
68  log_d_list, log_t_list, d_input, t_input, &
69  alpha_output, qbar_output, q0_output, kappa_e_output)
70 
71  ! alpha = alpha_output
72  ! Qbar = Qbar_output
73  ! Q0 = Q0_output
74  ! kappa_e = kappa_e_output
75 
76 end subroutine set_cak_opacity
77 
78 !> This routine reads out values and arguments from a table
79 subroutine read_table(D, T, K, filename)
80  !> 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
81 
82  double precision, intent(out) :: K(Dmin:Dmax,Tmin:Tmax), D(Dmin:Dmax), T(Tmin:Tmax)
83  character(*), intent(in) :: filename
84 
85  character :: dum
86  integer :: row, col
87 
88  OPEN(1,status = 'old', file=trim(fileplace)//filename)
89 
90  !> Read logT
91  READ(1,*) dum,t(tmin:tmax)
92 
93  !> Read T and K
94  do row = dmin,dmax !> NOT READING ENTIRE TABLE
95  READ(1,*) d(row), k(row,tmin:tmax)
96  enddo
97 
98  CLOSE(1)
99 
100 end subroutine read_table
101 
102 !>This subroutine looks in the table for the four couples (T,R)
103 !surrounding a given input for T and R
104 subroutine get_val_comb(K1_vals,K2_vals,K3_vals,K4_vals, &
105  Log_D_list, Log_T_list, D, T, &
106  K1, K2, K3, K4)
107 
108  double precision, intent(in) :: K1_vals(Dmin:Dmax,Tmin:Tmax)
109  double precision, intent(in) :: K2_vals(Dmin:Dmax,Tmin:Tmax)
110  double precision, intent(in) :: K3_vals(Dmin:Dmax,Tmin:Tmax)
111  double precision, intent(in) :: K4_vals(Dmin:Dmax,Tmin:Tmax)
112 
113  double precision, intent(in) :: Log_D_list(Dmin:Dmax)
114  double precision, intent(in) :: Log_T_list(Tmin:Tmax)
115  double precision, intent(in) :: D, T
116 
117  double precision, intent(out) :: K1
118  double precision, intent(out) :: K2
119  double precision, intent(out) :: K3
120  double precision, intent(out) :: K4
121 
122  integer :: low_r_index, up_r_index
123  integer :: low_t_index, up_t_index
124 
125  if (d .gt. maxval(log_d_list)) then
126  ! print*, 'Extrapolating in logR'
127  low_r_index = dmax-1
128  up_r_index = dmax
129  elseif (d .lt. minval(log_d_list)) then
130  ! print*, 'Extrapolating in logR'
131  low_r_index = dmin
132  up_r_index = dmin+1
133  else
134  call get_low_up_index(d, log_d_list, dmin, dmax, low_r_index, up_r_index)
135  endif
136 
137  if (t .gt. maxval(log_t_list)) then
138  ! print*, 'Extrapolating in logT'
139  low_t_index = tmax-1
140  up_t_index = tmax
141  elseif ( t .lt. minval(log_t_list)) then
142  ! print*, 'Extrapolating in logT'
143  low_t_index = tmin
144  up_t_index = tmin+1
145  else
146  call get_low_up_index(t, log_t_list, tmin, tmax, low_t_index, up_t_index)
147  endif
148 
149  call interpolate_krt(low_r_index, up_r_index, low_t_index, up_t_index, &
150  log_d_list, log_t_list, k1_vals, d, t, k1)
151 
152  call interpolate_krt(low_r_index, up_r_index, low_t_index, up_t_index, &
153  log_d_list, log_t_list, k2_vals, d, t, k2)
154 
155  call interpolate_krt(low_r_index, up_r_index, low_t_index, up_t_index, &
156  log_d_list, log_t_list, k3_vals, d, t, k3)
157 
158  call interpolate_krt(low_r_index, up_r_index, low_t_index, up_t_index, &
159  log_d_list, log_t_list, k4_vals, d, t, k4)
160 end subroutine get_val_comb
161 
162 
163 !> this subroutine finds the indexes in R and T arrays of the two values surrounding the input R and T
164 subroutine get_low_up_index(x, x_list, imin, imax, low_i, up_i)
165 
166  integer, intent(in) :: imin, imax
167  double precision, intent(in) :: x
168  double precision, intent(in) :: x_list(imin:imax)
169 
170  integer, intent(out) :: low_i, up_i
171 
172  double precision :: low_val, up_val
173  double precision :: res(imin:imax)
174 
175  res = x_list - x
176 
177  up_val = minval(res, mask = res .ge. 0) + x
178  low_val = maxval(res, mask = res .le. 0) + x
179 
180  up_i = minloc(abs(x_list - up_val),1) + imin -1
181  low_i = minloc(abs(x_list - low_val),1) + imin -1
182 
183 
184  if (up_i .eq. low_i) low_i = low_i - 1
185 
186 end subroutine get_low_up_index
187 
188 !> This subroutine does a bilinear interpolation in the R,T-plane
189 subroutine interpolate_krt(low_r, up_r, low_t, up_t, Log_D_list, Log_T_list, Kappa_vals, D, T, k_interp)
190 
191  integer, intent(in) :: low_r, up_r, low_t, up_t
192  double precision, intent(in) :: Kappa_vals(Dmin:Dmax,Tmin:Tmax)
193  double precision, intent(in) :: Log_D_list(Dmin:Dmax)
194  double precision, intent(in) :: Log_T_list(Tmin:Tmax)
195  double precision, intent(in) :: D,T
196  double precision, intent(out) :: k_interp
197 
198  double precision :: r1,r2,t1,t2
199  double precision :: k1, k2, k3, k4
200  double precision :: ka, kb
201 
202  !Cool ascii drawing of interpolation scheme: first interpolate twice in the T coord to get
203  !ka and kb, then interpolate in the R coord to get ki
204 
205 ! r_1 R r_2
206 ! | |
207 ! | |
208 ! ----k1--------ka-----k2----- t_1
209 ! | | |
210 ! | | |
211 ! T | | |
212 ! | | |
213 ! | ki |
214 ! | | |
215 ! ----k3--------kb-----k4----- t_2
216 ! | |
217 ! | |
218 
219 
220  r1 = log_d_list(low_r)
221  r2 = log_d_list(up_r)
222  t1 = log_t_list(low_t)
223  t2 = log_t_list(up_t)
224 
225  ! k1 = Kappa_vals(low_t, low_r)
226  ! k2 = Kappa_vals(low_t, up_r)
227  ! k3 = Kappa_vals(up_t, low_r)
228  ! k4 = Kappa_vals(up_t, up_r)
229 
230  k1 = kappa_vals(low_r, low_t)
231  k2 = kappa_vals(low_r, up_t)
232  k3 = kappa_vals(up_r, low_t)
233  k4 = kappa_vals(up_r, up_t)
234 
235  ! print*, 'surounding indexes'
236  ! print*, low_r, up_r, low_t, up_t
237  ! print*, 'surounding input values'
238  ! print*, r1,r2,t1,t2
239  ! print*, 'surounding table values'
240  ! print*, k1, k2, k3, k4
241 
242  call interpolate1d(r1,r2,d,k1,k2,ka)
243  call interpolate1d(r1,r2,d,k3,k4,kb)
244  call interpolate1d(t1,t2,t,ka,kb,k_interp)
245 
246  ! print*, 'interpolated value'
247  ! print*, ka, kb, k_interp
248 
249 end subroutine interpolate_krt
250 
251 
252 !> Interpolation in one dimension
253 subroutine interpolate1d(x1, x2, x, y1, y2, y)
254 
255  double precision, intent(in) :: x, x1, x2
256  double precision, intent(in) :: y1, y2
257  double precision, intent(out) :: y
258 
259  y = y1 + (x-x1)*(y2-y1)/(x2-x1)
260 
261 end subroutine interpolate1d
262 
263 end module mod_cak_opacity
264 
265 ! !> Interpolation on logarithmic scale
266 ! subroutine log_interpolate1D(x1, x2, x, y1, y2, y)
267 !
268 ! double precision, intent(in) :: x, x1, x2
269 ! double precision, intent(in) :: y1, y2
270 ! double precision, intent(out) :: y
271 !
272 ! double precision :: expx, expx1, expx2
273 ! double precision :: expy1, expy2
274 !
275 ! expx = 10**x
276 ! expx1 = 10**x1
277 ! expx2 = 10**x2
278 !
279 ! expy1 = 10**y1
280 ! expy2 = 10**y2
281 !
282 ! y = expy1 + (expx-expx1)*(expy2-expy1)/(expx2-expx1)
283 ! y = log10(y)
284 !
285 ! end subroutine log_interpolate1D
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, public set_cak_opacity(rho, temp, gradv, alpha_output, Qbar_output, Q0_output, kappa_e_output)
This subroutine calculates the opacity for a given temperature-density structure. The opacities are r...
double precision, dimension(dmin:dmax, tmin:tmax), public q0_vals
integer, parameter dmax
character(255), public amrvac_dir
integer, parameter tmax
double precision, dimension(dmin:dmax, tmin:tmax), public qbar_vals
double precision, dimension(dmin:dmax, tmin:tmax), public kappa_e_vals
subroutine get_val_comb(K1_vals, K2_vals, K3_vals, K4_vals, Log_D_list, Log_T_list, D, T, K1, K2, K3, K4)
This subroutine looks in the table for the four couples (T,R)
subroutine interpolate_krt(low_r, up_r, low_t, up_t, Log_D_list, Log_T_list, Kappa_vals, D, T, k_interp)
This subroutine does a bilinear interpolation in the R,T-plane.
subroutine interpolate1d(x1, x2, x, y1, y2, y)
Interpolation in one dimension.
integer, parameter dmin
min and max indices for R,T-range in opacity table
subroutine read_table(D, T, K, filename)
This routine reads out values and arguments from a table.
double precision, dimension(tmin:tmax), public log_t_list
double precision, dimension(dmin:dmax, tmin:tmax), public alpha_vals
The opacity tables are read once and stored globally in Kappa_vals.
character(255), public fileplace
integer, parameter tmin
subroutine, public init_cak(tablename)
This routine is called when the fld radiation module is initialised. Here, the tables for different H...
double precision, dimension(dmin:dmax), public log_d_list