Line data Source code
1 : ! ***********************************************************************
2 : !
3 : ! Copyright (C) 2010-2019 The MESA Team
4 : !
5 : ! This program is free software: you can redistribute it and/or modify
6 : ! it under the terms of the GNU Lesser General Public License
7 : ! as published by the Free Software Foundation,
8 : ! either version 3 of the License, or (at your option) any later version.
9 : !
10 : ! This program is distributed in the hope that it will be useful,
11 : ! but WITHOUT ANY WARRANTY; without even the implied warranty of
12 : ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 : ! See the GNU Lesser General Public License for more details.
14 : !
15 : ! You should have received a copy of the GNU Lesser General Public License
16 : ! along with this program. If not, see <https://www.gnu.org/licenses/>.
17 : !
18 : ! ***********************************************************************
19 :
20 : module eosDT_eval
21 :
22 : use eos_def
23 : use const_def, only: avo, crad, ln10, arg_not_provided, mp, kerg, dp, qp
24 : use utils_lib, only: is_bad, mesa_error
25 : use math_lib
26 : use eosDT_load_tables, only: load_single_eosDT_table_by_id
27 : use eos_HELM_eval
28 : use eoscms_eval, only: Get_CMS_alfa, get_CMS_for_eosdt
29 : use skye, only: get_Skye_for_eosdt, get_Skye_alfa, get_Skye_alfa_simple
30 : use ideal, only: get_ideal_for_eosdt
31 :
32 : implicit none
33 :
34 : logical, parameter :: return_ierr_beyond_table_bounds = .true.
35 :
36 : integer, parameter :: use_none = 1
37 : integer, parameter :: use_all = 2
38 : integer, parameter :: blend_in_x = 3
39 : integer, parameter :: blend_in_y = 4
40 : integer, parameter :: blend_corner_out = 5
41 : integer, parameter :: blend_corner_in = 6
42 : integer, parameter :: blend_diagonal = 7
43 : integer, parameter :: blend_in_Z = 8
44 :
45 : abstract interface
46 : subroutine get_values_for_eosdt_interface( &
47 : handle, dbg, Z, X, abar, zbar, &
48 : species, chem_id, net_iso, xa, &
49 : rho, logRho, T, logT, remaining_fraction, &
50 : res, d_dlnd, d_dlnT, d_dxa, &
51 : skip, ierr)
52 : use const_def, only: dp
53 : use eos_def, only: nv
54 : implicit none
55 : integer, intent(in) :: handle
56 : logical, intent(in) :: dbg
57 : real(dp), intent(in) :: &
58 : Z, X, abar, zbar, remaining_fraction
59 : integer, intent(in) :: species
60 : integer, pointer :: chem_id(:), net_iso(:)
61 : real(dp), intent(in) :: xa(:)
62 : real(dp), intent(in) :: rho, logRho, T, logT
63 : real(dp), intent(inout), dimension(nv) :: &
64 : res, d_dlnd, d_dlnT
65 : real(dp), intent(inout), dimension(nv, species) :: d_dxa
66 : logical, intent(out) :: skip
67 : integer, intent(out) :: ierr
68 : end subroutine get_values_for_eosdt_interface
69 : end interface
70 :
71 :
72 : contains
73 :
74 :
75 0 : subroutine Test_one_eosDT_component(rq, which_eos, &
76 : Z, X, abar, zbar, &
77 0 : species, chem_id, net_iso, xa, &
78 : arho, alogrho, atemp, alogtemp, &
79 0 : res, d_dlnd, d_dlnT, d_dxa, ierr)
80 : type (EoS_General_Info), pointer :: rq
81 : real(dp), intent(in) :: Z, X, abar, zbar
82 : integer, intent(in) :: which_eos, species
83 : integer, pointer :: chem_id(:), net_iso(:)
84 : real(dp), intent(in) :: xa(:)
85 : real(dp), intent(in) :: arho, alogrho, atemp, alogtemp
86 : real(dp), intent(inout), dimension(nv) :: res, d_dlnd, d_dlnT
87 : real(dp), intent(inout), dimension(nv, species) :: d_dxa
88 : integer, intent(out) :: ierr
89 :
90 0 : real(dp) :: rho, logRho, T, logT
91 : logical :: skip
92 :
93 : include 'formats'
94 :
95 0 : T = atemp; logT = alogtemp
96 0 : if (atemp == arg_not_provided .and. alogtemp == arg_not_provided) then
97 0 : ierr = -1; return
98 : end if
99 0 : if (alogtemp == arg_not_provided) logT = log10(T)
100 0 : if (atemp == arg_not_provided) T = exp10(logT)
101 :
102 0 : if (T <= 0) then
103 0 : ierr = -1
104 0 : return
105 : end if
106 :
107 0 : Rho = arho; logrho = alogrho
108 0 : if (arho == arg_not_provided .and. alogrho == arg_not_provided) then
109 0 : ierr = -1; return
110 : end if
111 0 : if (alogrho == arg_not_provided) logRho = log10(Rho)
112 0 : if (arho == arg_not_provided) Rho = exp10(logRho)
113 :
114 0 : if (Rho <= 0) then
115 0 : ierr = -1
116 0 : return
117 : end if
118 0 : if (is_bad(Rho) .or. is_bad(T)) then
119 0 : ierr = -1
120 0 : return
121 : end if
122 :
123 0 : select case(which_eos)
124 : case(i_eos_HELM)
125 : call get_helm_for_eosdt( &
126 : rq% handle, dbg, Z, X, abar, zbar, &
127 : species, chem_id, net_iso, xa, &
128 : rho, logRho, T, logT, 1d0, &
129 : res, d_dlnd, d_dlnT, d_dxa, &
130 0 : skip, ierr)
131 : case(i_eos_OPAL_SCVH)
132 : call get_opal_scvh_for_eosdt( &
133 : rq% handle, dbg, Z, X, abar, zbar, &
134 : species, chem_id, net_iso, xa, &
135 : rho, logRho, T, logT, 1d0, &
136 : res, d_dlnd, d_dlnT, d_dxa, &
137 0 : skip, ierr)
138 : case(i_eos_FreeEOS)
139 : call get_FreeEOS_for_eosdt( &
140 : rq% handle, dbg, Z, X, abar, zbar, &
141 : species, chem_id, net_iso, xa, &
142 : rho, logRho, T, logT, 1d0, &
143 : res, d_dlnd, d_dlnT, d_dxa, &
144 0 : skip, ierr)
145 : case(i_eos_PC)
146 : call get_PC_for_eosdt( &
147 : rq% handle, dbg, Z, X, abar, zbar, &
148 : species, chem_id, net_iso, xa, &
149 : rho, logRho, T, logT, 1d0, &
150 : res, d_dlnd, d_dlnT, d_dxa, &
151 0 : skip, ierr)
152 : case(i_eos_Skye)
153 : call get_Skye_for_eosdt( &
154 : rq% handle, dbg, Z, X, abar, zbar, &
155 : species, chem_id, net_iso, xa, &
156 : rho, logRho, T, logT, 1d0, &
157 : res, d_dlnd, d_dlnT, d_dxa, &
158 0 : skip, ierr)
159 : case(i_eos_CMS)
160 : call get_CMS_for_eosdt( &
161 : rq% handle, dbg, Z, X, abar, zbar, &
162 : species, chem_id, net_iso, xa, &
163 : rho, logRho, T, logT, 1d0, &
164 : res, d_dlnd, d_dlnT, d_dxa, &
165 0 : skip, ierr)
166 : case(i_eos_ideal)
167 : call get_ideal_for_eosdt( &
168 : rq% handle, dbg, Z, X, abar, zbar, &
169 : species, chem_id, net_iso, xa, &
170 : rho, logRho, T, logT, 1d0, &
171 : res, d_dlnd, d_dlnT, d_dxa, &
172 0 : skip, ierr)
173 : case default
174 0 : ierr = -1
175 : end select
176 :
177 0 : if (ierr /= 0) then
178 0 : write(*,*) 'failed in Test_one_eosDT_component', which_eos
179 0 : return
180 : end if
181 :
182 0 : if (skip) then
183 0 : write(*,*) 'skipped - no results Test_one_eosDT_component', which_eos
184 0 : return
185 : end if
186 :
187 : end subroutine Test_one_eosDT_component
188 :
189 :
190 241252 : subroutine Get_eosDT_Results(rq, &
191 : Z, X, abar, zbar, &
192 241252 : species, chem_id, net_iso, xa, &
193 : arho, alogrho, atemp, alogtemp, &
194 241252 : res, d_dlnd, d_dlnT, d_dxa, ierr)
195 : type (EoS_General_Info), pointer :: rq
196 : real(dp), intent(in) :: Z, X, abar, zbar
197 : integer, intent(in) :: species
198 : integer, pointer :: chem_id(:), net_iso(:)
199 : real(dp), intent(in) :: xa(:)
200 : real(dp), intent(in) :: arho, alogrho, atemp, alogtemp
201 : real(dp), intent(inout), dimension(nv) :: res, d_dlnd, d_dlnT
202 : real(dp), intent(inout), dimension(nv, species) :: d_dxa
203 : integer, intent(out) :: ierr
204 :
205 241252 : real(dp) :: rho, logRho, T, logT
206 : logical :: skip, dbg
207 :
208 : include 'formats'
209 :
210 :
211 241252 : T = atemp; logT = alogtemp
212 241252 : if (atemp == arg_not_provided .and. alogtemp == arg_not_provided) then
213 0 : ierr = -1; return
214 : end if
215 241252 : if (alogtemp == arg_not_provided) logT = log10(T)
216 241252 : if (atemp == arg_not_provided) T = exp10(logT)
217 :
218 241252 : if (T <= 0) then
219 0 : ierr = -1
220 0 : return
221 : end if
222 :
223 241252 : Rho = arho; logrho = alogrho
224 241252 : if (arho == arg_not_provided .and. alogrho == arg_not_provided) then
225 0 : ierr = -1; return
226 : end if
227 241252 : if (alogrho == arg_not_provided) logRho = log10(Rho)
228 241252 : if (arho == arg_not_provided) Rho = exp10(logRho)
229 :
230 241252 : if (Rho <= 0) then
231 0 : ierr = -1
232 0 : return
233 : end if
234 241252 : if (is_bad(Rho) .or. is_bad(T)) then
235 0 : ierr = -1
236 0 : return
237 : end if
238 :
239 241252 : dbg = rq% dbg
240 241252 : if (dbg) dbg = & ! check limits
241 : logT >= rq% logT_lo .and. logT <= rq% logT_hi .and. &
242 : logRho >= rq% logRho_lo .and. logRho <= rq% logRho_hi .and. &
243 : X >= rq% X_lo .and. X <= rq% X_hi .and. &
244 0 : Z >= rq% Z_lo .and. Z <= rq% Z_hi
245 :
246 : call get_level0_for_eosdt( &
247 : rq% handle, dbg, Z, X, abar, zbar, &
248 : species, chem_id, net_iso, xa, &
249 : rho, logRho, T, logT, 1d0, &
250 : res, d_dlnd, d_dlnT, d_dxa, &
251 241252 : skip, ierr)
252 241252 : if (skip) ierr = -1
253 241252 : if (ierr /= 0) return
254 :
255 : ! opportunity for the user to modify the eos results
256 241252 : if (rq% use_other_eos_results) then
257 : call rq% other_eos_results( &
258 : rq% handle, &
259 : species, chem_id, net_iso, xa, &
260 : Rho, logRho, T, logT, &
261 0 : res, d_dlnd, d_dlnT, d_dxa, ierr)
262 : end if
263 :
264 241252 : if (eos_test_partials) then
265 0 : eos_test_partials_val = abar
266 0 : eos_test_partials_dval_dx = 0
267 0 : write(*,*) 'eos_test_partials'
268 : end if
269 :
270 : end subroutine Get_eosDT_Results
271 :
272 :
273 0 : subroutine get_other_for_eosdt( &
274 : handle, dbg, Z, X, abar, zbar, &
275 0 : species, chem_id, net_iso, xa, &
276 : rho, logRho, T, logT, remaining_fraction, &
277 0 : res, d_dlnd, d_dlnT, d_dxa, &
278 : skip, ierr)
279 : integer, intent(in) :: handle
280 : logical, intent(in) :: dbg
281 : real(dp), intent(in) :: &
282 : Z, X, abar, zbar, remaining_fraction
283 : integer, intent(in) :: species
284 : integer, pointer :: chem_id(:), net_iso(:)
285 : real(dp), intent(in) :: xa(:)
286 : real(dp), intent(in) :: rho, logRho, T, logT
287 : real(dp), intent(inout), dimension(nv) :: &
288 : res, d_dlnd, d_dlnT
289 : real(dp), intent(inout), dimension(nv, species) :: d_dxa
290 : logical, intent(out) :: skip
291 : integer, intent(out) :: ierr
292 :
293 : type (EoS_General_Info), pointer :: rq
294 :
295 0 : rq => eos_handles(handle)
296 :
297 : ierr = 0
298 :
299 : call rq% other_eos_component( &
300 : handle, &
301 : species, chem_id, net_iso, xa, &
302 : rho, logRho, T, logT, &
303 : res, d_dlnd, d_dlnT, d_dxa, &
304 0 : ierr)
305 :
306 : ! zero all frac components
307 0 : res(i_frac:i_frac+num_eos_frac_results-1) = 0.0d0
308 0 : d_dlnd(i_frac:i_frac+num_eos_frac_results-1) = 0.0d0
309 0 : d_dlnT(i_frac:i_frac+num_eos_frac_results-1) = 0.0d0
310 :
311 0 : skip = .false.
312 :
313 0 : end subroutine get_other_for_eosdt
314 :
315 :
316 241252 : subroutine get_level0_for_eosdt( & ! other
317 : handle, dbg, Z, X, abar, zbar, &
318 241252 : species, chem_id, net_iso, xa, &
319 : rho, logRho, T, logT, remaining_fraction, &
320 241252 : res, d_dlnd, d_dlnT, d_dxa, &
321 : skip, ierr)
322 : integer, intent(in) :: handle
323 : logical, intent(in) :: dbg
324 : real(dp), intent(in) :: Z, X, abar, zbar, remaining_fraction
325 : integer, intent(in) :: species
326 : integer, pointer :: chem_id(:), net_iso(:)
327 : real(dp), intent(in) :: xa(:)
328 : real(dp), intent(in) :: rho, logRho, T, logT
329 : real(dp), intent(inout), dimension(nv) :: &
330 : res, d_dlnd, d_dlnT
331 : real(dp), intent(inout), dimension(nv, species) :: d_dxa
332 : logical, intent(out) :: skip
333 : integer, intent(out) :: ierr
334 :
335 241252 : real(dp) :: frac, d_frac_dlogT, d_frac_dlogRho
336 241252 : real(dp) :: alfa, d_alfa_dlogT, d_alfa_dlogRho
337 : type (EoS_General_Info), pointer :: rq
338 : procedure (get_values_for_eosdt_interface), pointer :: get_1st, get_2nd
339 :
340 : include 'formats'
341 :
342 241252 : ierr = 0
343 241252 : rq => eos_handles(handle)
344 :
345 241252 : if (rq% use_other_eos_component) then
346 : call rq% other_eos_frac( &
347 : handle, &
348 : species, chem_id, net_iso, xa, &
349 : rho, logRho, T, logT, &
350 : frac, d_frac_dlogRho, d_frac_dlogT, &
351 0 : ierr)
352 0 : if (ierr /= 0) return
353 0 : alfa = 1d0 - frac
354 0 : d_alfa_dlogT = -d_frac_dlogT
355 0 : d_alfa_dlogRho = -d_frac_dlogRho
356 : else
357 241252 : alfa = 1d0 ! no other
358 241252 : d_alfa_dlogT = 0d0
359 241252 : d_alfa_dlogRho = 0d0
360 : end if
361 :
362 241252 : if (dbg) write(*,1) 'other', (1d0 - alfa)*remaining_fraction
363 :
364 241252 : get_1st => get_other_for_eosdt
365 241252 : get_2nd => get_level1_for_eosdt
366 : call combine_for_eosdt( &
367 : get_1st, get_2nd, alfa*remaining_fraction, &
368 : alfa, d_alfa_dlogT, d_alfa_dlogRho, &
369 : rq, dbg, Z, X, abar, zbar, &
370 : species, chem_id, net_iso, xa, &
371 : rho, logRho, T, logT, &
372 : res, d_dlnd, d_dlnT, d_dxa, &
373 241252 : skip, ierr)
374 241252 : if (ierr /= 0 .and. rq% okay_to_convert_ierr_to_skip) then
375 0 : skip = .true.
376 0 : ierr = 0
377 : end if
378 :
379 : end subroutine get_level0_for_eosdt
380 :
381 :
382 241252 : subroutine get_level1_for_eosdt( & ! CMS
383 : handle, dbg, Z, X, abar, zbar, &
384 241252 : species, chem_id, net_iso, xa, &
385 : rho, logRho, T, logT, remaining_fraction, &
386 241252 : res, d_dlnd, d_dlnT, d_dxa, &
387 : skip, ierr)
388 : use eoscms_eval, only: Get_CMS_alfa, get_CMS_for_eosdt
389 : integer, intent(in) :: handle
390 : logical, intent(in) :: dbg
391 : real(dp), intent(in) :: Z, X, abar, zbar, remaining_fraction
392 : integer, intent(in) :: species
393 : integer, pointer :: chem_id(:), net_iso(:)
394 : real(dp), intent(in) :: xa(:)
395 : real(dp), intent(in) :: rho, logRho, T, logT
396 : real(dp), intent(inout), dimension(nv) :: &
397 : res, d_dlnd, d_dlnT
398 : real(dp), intent(inout), dimension(nv, species) :: d_dxa
399 : logical, intent(out) :: skip
400 : integer, intent(out) :: ierr
401 :
402 241252 : real(dp) :: alfa, d_alfa_dlogT, d_alfa_dlogRho
403 : type (EoS_General_Info), pointer :: rq
404 : procedure (get_values_for_eosdt_interface), pointer :: get_1st, get_2nd
405 :
406 : include 'formats'
407 :
408 241252 : ierr = 0
409 241252 : rq => eos_handles(handle)
410 :
411 241252 : if (rq% use_CMS) then
412 : call Get_CMS_alfa( &
413 : rq, logRho, logT, Z, abar, zbar, &
414 : alfa, d_alfa_dlogT, d_alfa_dlogRho, &
415 0 : ierr)
416 0 : if (ierr /= 0) return
417 : else
418 241252 : alfa = 1d0 ! no CMS
419 241252 : d_alfa_dlogT = 0d0
420 241252 : d_alfa_dlogRho = 0d0
421 : end if
422 :
423 241252 : if (dbg) write(*,1) 'CMS', (1d0 - alfa)*remaining_fraction
424 :
425 241252 : get_1st => get_CMS_for_eosdt
426 241252 : get_2nd => get_level2_for_eosdt
427 : call combine_for_eosdt( &
428 : get_1st, get_2nd, alfa*remaining_fraction, &
429 : alfa, d_alfa_dlogT, d_alfa_dlogRho, &
430 : rq, dbg, Z, X, abar, zbar, &
431 : species, chem_id, net_iso, xa, &
432 : rho, logRho, T, logT, &
433 : res, d_dlnd, d_dlnT, d_dxa, &
434 241252 : skip, ierr)
435 241252 : if (ierr /= 0 .and. rq% okay_to_convert_ierr_to_skip) then
436 0 : skip = .true.
437 0 : ierr = 0
438 : end if
439 :
440 241252 : end subroutine get_level1_for_eosdt
441 :
442 :
443 241252 : subroutine get_level2_for_eosdt( & ! Skye
444 : handle, dbg, Z, X, abar, zbar, &
445 241252 : species, chem_id, net_iso, xa, &
446 : rho, logRho, T, logT, remaining_fraction, &
447 241252 : res, d_dlnd, d_dlnT, d_dxa, &
448 : skip, ierr)
449 : integer, intent(in) :: handle
450 : logical, intent(in) :: dbg
451 : real(dp), intent(in) :: Z, X, abar, zbar, remaining_fraction
452 : integer, intent(in) :: species
453 : integer, pointer :: chem_id(:), net_iso(:)
454 : real(dp), intent(in) :: xa(:)
455 : real(dp), intent(in) :: rho, logRho, T, logT
456 : real(dp), intent(inout), dimension(nv) :: &
457 : res, d_dlnd, d_dlnT
458 : real(dp), intent(inout), dimension(nv, species) :: d_dxa
459 : logical, intent(out) :: skip
460 : integer, intent(out) :: ierr
461 :
462 241252 : real(dp) :: alfa, d_alfa_dlogT, d_alfa_dlogRho
463 : type (EoS_General_Info), pointer :: rq
464 : procedure (get_values_for_eosdt_interface), pointer :: get_1st, get_2nd
465 :
466 : include 'formats'
467 :
468 241252 : ierr = 0
469 241252 : rq => eos_handles(handle)
470 :
471 241252 : if (rq% use_Skye) then
472 241252 : if (rq% use_simple_Skye_blends) then
473 : call Get_Skye_alfa_simple( &
474 : rq, logRho, logT, Z, abar, zbar, &
475 : alfa, d_alfa_dlogT, d_alfa_dlogRho, &
476 0 : ierr)
477 : else
478 : call Get_Skye_alfa( &
479 : rq, logRho, logT, Z, abar, zbar, &
480 : alfa, d_alfa_dlogT, d_alfa_dlogRho, &
481 241252 : ierr)
482 : end if
483 241252 : if (ierr /= 0) return
484 : else
485 0 : alfa = 1d0 ! no Skye
486 0 : d_alfa_dlogT = 0d0
487 0 : d_alfa_dlogRho = 0d0
488 : end if
489 :
490 241252 : if (dbg) write(*,1) 'Skye', (1d0 - alfa)*remaining_fraction
491 241252 : get_1st => get_Skye_for_eosdt
492 :
493 241252 : get_2nd => get_level3_for_eosdt
494 : call combine_for_eosdt( &
495 : get_1st, get_2nd, alfa*remaining_fraction, &
496 : alfa, d_alfa_dlogT, d_alfa_dlogRho, &
497 : rq, dbg, Z, X, abar, zbar, &
498 : species, chem_id, net_iso, xa, &
499 : rho, logRho, T, logT, &
500 : res, d_dlnd, d_dlnT, d_dxa, &
501 241252 : skip, ierr)
502 241252 : if (ierr /= 0 .and. rq% okay_to_convert_ierr_to_skip) then
503 0 : skip = .true.
504 0 : ierr = 0
505 : end if
506 :
507 241252 : end subroutine get_level2_for_eosdt
508 :
509 :
510 210666 : subroutine get_level3_for_eosdt( & ! PC
511 : handle, dbg, Z, X, abar, zbar, &
512 210666 : species, chem_id, net_iso, xa, &
513 : rho, logRho, T, logT, remaining_fraction, &
514 210666 : res, d_dlnd, d_dlnT, d_dxa, &
515 : skip, ierr)
516 : use eospc_eval, only: Get_PC_alfa, get_PC_for_eosdt
517 : integer, intent(in) :: handle
518 : logical, intent(in) :: dbg
519 : real(dp), intent(in) :: Z, X, abar, zbar, remaining_fraction
520 : integer, intent(in) :: species
521 : integer, pointer :: chem_id(:), net_iso(:)
522 : real(dp), intent(in) :: xa(:)
523 : real(dp), intent(in) :: rho, logRho, T, logT
524 : real(dp), intent(inout), dimension(nv) :: &
525 : res, d_dlnd, d_dlnT
526 : real(dp), intent(inout), dimension(nv, species) :: d_dxa
527 : logical, intent(out) :: skip
528 : integer, intent(out) :: ierr
529 :
530 210666 : real(dp) :: alfa, d_alfa_dlogT, d_alfa_dlogRho
531 : type (EoS_General_Info), pointer :: rq
532 : procedure (get_values_for_eosdt_interface), pointer :: get_1st, get_2nd
533 :
534 : include 'formats'
535 :
536 210666 : ierr = 0
537 210666 : rq => eos_handles(handle)
538 :
539 210666 : if (rq% use_PC) then
540 : call Get_PC_alfa( &
541 : rq, logRho, logT, Z, abar, zbar, &
542 : alfa, d_alfa_dlogT, d_alfa_dlogRho, &
543 0 : ierr)
544 0 : if (ierr /= 0) return
545 : else
546 210666 : alfa = 1d0 ! no PC
547 210666 : d_alfa_dlogT = 0d0
548 210666 : d_alfa_dlogRho = 0d0
549 : end if
550 :
551 210666 : if (dbg) write(*,1) 'PC', (1d0 - alfa)*remaining_fraction
552 210666 : get_1st => get_PC_for_eosdt
553 :
554 210666 : get_2nd => get_level4_for_eosdt
555 : call combine_for_eosdt( &
556 : get_1st, get_2nd, alfa*remaining_fraction, &
557 : alfa, d_alfa_dlogT, d_alfa_dlogRho, &
558 : rq, dbg, Z, X, abar, zbar, &
559 : species, chem_id, net_iso, xa, &
560 : rho, logRho, T, logT, &
561 : res, d_dlnd, d_dlnT, d_dxa, &
562 210666 : skip, ierr)
563 210666 : if (ierr /= 0 .and. rq% okay_to_convert_ierr_to_skip) then
564 0 : skip = .true.
565 0 : ierr = 0
566 : end if
567 :
568 210666 : end subroutine get_level3_for_eosdt
569 :
570 :
571 210666 : subroutine get_level4_for_eosdt( & ! FreeEOS
572 : handle, dbg, Z, X, abar, zbar, &
573 210666 : species, chem_id, net_iso, xa, &
574 : rho, logRho, T, logT, remaining_fraction, &
575 210666 : res, d_dlnd, d_dlnT, d_dxa, &
576 : skip, ierr)
577 210666 : use skye, only: get_Skye_for_eosdt, get_Skye_alfa
578 : integer, intent(in) :: handle
579 : logical, intent(in) :: dbg
580 : real(dp), intent(in) :: Z, X, abar, zbar, remaining_fraction
581 : integer, intent(in) :: species
582 : integer, pointer :: chem_id(:), net_iso(:)
583 : real(dp), intent(in) :: xa(:)
584 : real(dp), intent(in) :: rho, logRho, T, logT
585 : real(dp), intent(inout), dimension(nv) :: &
586 : res, d_dlnd, d_dlnT
587 : real(dp), intent(inout), dimension(nv, species) :: d_dxa
588 : logical, intent(out) :: skip
589 : integer, intent(out) :: ierr
590 :
591 210666 : real(dp) :: alfa, d_alfa_dlogT, d_alfa_dlogRho
592 : type (EoS_General_Info), pointer :: rq
593 : procedure (get_values_for_eosdt_interface), pointer :: get_1st, get_2nd
594 :
595 : include 'formats'
596 :
597 210666 : ierr = 0
598 210666 : rq => eos_handles(handle)
599 :
600 210666 : if (rq% use_FreeEOS) then
601 : call Get_FreeEOS_alfa( &
602 : rq, dbg, logRho, logT, Z, abar, zbar, &
603 : alfa, d_alfa_dlogT, d_alfa_dlogRho, &
604 210666 : ierr)
605 210666 : if (ierr /= 0) return
606 : else
607 0 : alfa = 1d0 ! no FreeEOS
608 0 : d_alfa_dlogT = 0d0
609 0 : d_alfa_dlogRho = 0d0
610 : end if
611 :
612 210666 : if (dbg) write(*,1) 'FreeEOS', (1d0 - alfa)*remaining_fraction
613 210666 : get_1st => get_FreeEOS_for_eosdt
614 :
615 210666 : get_2nd => get_level5_for_eosdt
616 : call combine_for_eosdt( &
617 : get_1st, get_2nd, alfa*remaining_fraction, &
618 : alfa, d_alfa_dlogT, d_alfa_dlogRho, &
619 : rq, dbg, Z, X, abar, zbar, &
620 : species, chem_id, net_iso, xa, &
621 : rho, logRho, T, logT, &
622 : res, d_dlnd, d_dlnT, d_dxa, &
623 210666 : skip, ierr)
624 210666 : if (ierr /= 0 .and. rq% okay_to_convert_ierr_to_skip) then
625 0 : skip = .true.
626 0 : ierr = 0
627 : end if
628 :
629 210666 : end subroutine get_level4_for_eosdt
630 :
631 :
632 70 : subroutine get_level5_for_eosdt( & ! OPAL/SCVH
633 : handle, dbg, Z, X, abar, zbar, &
634 70 : species, chem_id, net_iso, xa, &
635 : rho, logRho, T_in, logT_in, remaining_fraction, &
636 70 : res, d_dlnd, d_dlnT, d_dxa, &
637 : skip, ierr)
638 : integer, intent(in) :: handle
639 : logical, intent(in) :: dbg
640 : real(dp), intent(in) :: &
641 : Z, X, abar, zbar, remaining_fraction
642 : integer, intent(in) :: species
643 : integer, pointer :: chem_id(:), net_iso(:)
644 : real(dp), intent(in) :: xa(:)
645 : real(dp), intent(in) :: rho, logRho, T_in, logT_in
646 : real(dp), intent(inout), dimension(nv) :: &
647 : res, d_dlnd, d_dlnT
648 : real(dp), intent(inout), dimension(nv, species) :: d_dxa
649 : logical, intent(out) :: skip
650 : integer, intent(out) :: ierr
651 :
652 70 : real(dp) :: alfa, d_alfa_dlogT, d_alfa_dlogRho, &
653 : logT_HELM, T_HELM, logQ, logQ2, T, logT
654 : type (EoS_General_Info), pointer :: rq
655 : procedure (get_values_for_eosdt_interface), pointer :: get_1st, get_2nd
656 :
657 : include 'formats'
658 :
659 70 : ierr = 0
660 70 : rq => eos_handles(handle)
661 :
662 70 : T = T_in
663 70 : logT = logT_in
664 :
665 70 : if (rq% use_OPAL_SCVH) then
666 : call get_opal_scvh_alfa_and_partials( &
667 : rq, logT, logRho, Z, &
668 70 : alfa, d_alfa_dlogRho, d_alfa_dlogT, ierr)
669 70 : if (ierr /= 0) return
670 : else
671 0 : alfa = 1d0 ! no OPAL_SCVH
672 0 : d_alfa_dlogT = 0d0
673 0 : d_alfa_dlogRho = 0d0
674 : end if
675 :
676 70 : if (dbg) write(*,1) 'OPAL/SCVH', (1d0 - alfa)*remaining_fraction
677 70 : get_1st => get_opal_scvh_for_eosdt
678 :
679 70 : get_2nd => get_level6_for_eosdt
680 : call combine_for_eosdt( &
681 : get_1st, get_2nd, alfa*remaining_fraction, &
682 : alfa, d_alfa_dlogT, d_alfa_dlogRho, &
683 : rq, dbg, Z, X, abar, zbar, &
684 : species, chem_id, net_iso, xa, &
685 : rho, logRho, T, logT, &
686 : res, d_dlnd, d_dlnT, d_dxa, &
687 70 : skip, ierr)
688 70 : if (ierr /= 0 .and. rq% okay_to_convert_ierr_to_skip) then
689 0 : skip = .true.
690 0 : ierr = 0
691 : end if
692 :
693 210666 : end subroutine get_level5_for_eosdt
694 :
695 0 : subroutine get_level6_for_eosdt( & ! HELM/ideal
696 : handle, dbg, Z, X, abar, zbar, &
697 0 : species, chem_id, net_iso, xa, &
698 : rho, logRho, T_in, logT_in, remaining_fraction, &
699 0 : res, d_dlnd, d_dlnT, d_dxa, &
700 : skip, ierr)
701 : integer, intent(in) :: handle
702 : logical, intent(in) :: dbg
703 : real(dp), intent(in) :: &
704 : Z, X, abar, zbar, remaining_fraction
705 : integer, intent(in) :: species
706 : integer, pointer :: chem_id(:), net_iso(:)
707 : real(dp), intent(in) :: xa(:)
708 : real(dp), intent(in) :: rho, logRho, T_in, logT_in
709 : real(dp), intent(inout), dimension(nv) :: &
710 : res, d_dlnd, d_dlnT
711 : real(dp), intent(inout), dimension(nv, species) :: d_dxa
712 : logical, intent(out) :: skip
713 : integer, intent(out) :: ierr
714 :
715 : real(dp) :: alfa, d_alfa_dlogT, d_alfa_dlogRho, &
716 : logT_HELM, T_HELM, logQ, logQ2, T, logT
717 : type (EoS_General_Info), pointer :: rq
718 : procedure (get_values_for_eosdt_interface), pointer :: get_1st, get_2nd
719 :
720 : include 'formats'
721 :
722 : ierr = 0
723 0 : rq => eos_handles(handle)
724 :
725 0 : T = T_in
726 0 : logT = logT_in
727 :
728 0 : call get_HELM_alfa(rq, logRho, logT, alfa, d_alfa_dlogRho, d_alfa_dlogT, ierr)
729 :
730 0 : if (dbg) write(*,1) 'HELM', (1d0 - alfa)*remaining_fraction
731 :
732 0 : get_1st => get_helm_for_eosdt
733 0 : get_2nd => get_ideal_for_eosdt
734 : call combine_for_eosdt( &
735 : get_1st, get_2nd, alfa*remaining_fraction, &
736 : alfa, d_alfa_dlogT, d_alfa_dlogRho, &
737 : rq, dbg, Z, X, abar, zbar, &
738 : species, chem_id, net_iso, xa, &
739 : rho, logRho, T, logT, &
740 : res, d_dlnd, d_dlnT, d_dxa, &
741 0 : skip, ierr)
742 0 : if (ierr /= 0 .and. rq% okay_to_convert_ierr_to_skip) then
743 0 : skip = .true.
744 0 : ierr = 0
745 : end if
746 :
747 0 : end subroutine get_level6_for_eosdt
748 :
749 0 : subroutine get_HELM_alfa( &
750 : rq, logRho, logT, alfa, d_alfa_dlogT, d_alfa_dlogRho, ierr)
751 : use const_def, only: dp
752 : use eos_blend
753 : use auto_diff
754 : type (EoS_General_Info), pointer :: rq
755 : real(dp), intent(in) :: logRho, logT
756 : real(dp), intent(out) :: alfa, d_alfa_dlogT, d_alfa_dlogRho
757 : integer, intent(out) :: ierr
758 :
759 : logical :: contained
760 : type(auto_diff_real_2var_order1) :: p(2), blend, dist
761 :
762 : ! Blend parameters
763 0 : real(dp) :: helm_blend_width
764 : integer, parameter :: num_points = 4
765 0 : real(dp) :: bounds(4,2)
766 : type (Helm_Table), pointer :: ht
767 :
768 0 : ierr = 0
769 0 : ht => eos_ht
770 0 : helm_blend_width = 0.1d0
771 :
772 0 : bounds(1,1) = ht% logdlo
773 0 : bounds(1,2) = ht% logthi
774 :
775 0 : bounds(2,1) = ht% logdlo
776 0 : bounds(2,2) = ht% logtlo
777 :
778 0 : bounds(3,1) = ht% logdhi
779 0 : bounds(3,2) = ht% logtlo
780 :
781 0 : bounds(4,1) = ht% logdhi
782 0 : bounds(4,2) = ht% logthi
783 :
784 : ! Set up auto_diff point
785 0 : p(1) = logRho
786 0 : p(1)%d1val1 = 1d0
787 0 : p(2) = logT
788 0 : p(2)%d1val2 = 1d0
789 :
790 0 : contained = is_contained(num_points, bounds, p)
791 0 : dist = min_distance_to_polygon(num_points, bounds, p)
792 :
793 0 : if (contained) then ! Make distance negative for points inside the polygon
794 0 : dist = -dist
795 : end if
796 :
797 0 : dist = dist / helm_blend_width
798 0 : blend = max(dist, 0d0)
799 0 : blend = min(blend, 1d0)
800 :
801 0 : alfa = blend%val
802 0 : d_alfa_dlogRho = blend%d1val1
803 0 : d_alfa_dlogT = blend%d1val2
804 :
805 0 : end subroutine get_HELM_alfa
806 :
807 :
808 210666 : subroutine Get_FreeEOS_alfa( &
809 : rq, dbg, logRho, logT, Z, abar, zbar, &
810 : alfa, d_alfa_dlogT, d_alfa_dlogRho, &
811 : ierr)
812 0 : use const_def, only: dp
813 : use auto_diff
814 : type (EoS_General_Info), pointer :: rq
815 : logical, intent(in) :: dbg
816 : real(dp), intent(in) :: logRho, logT, Z, abar, zbar
817 : real(dp), intent(out) :: alfa, d_alfa_dlogT, d_alfa_dlogRho
818 : integer, intent(out) :: ierr
819 210666 : real(dp) :: logQ_cut_lo, logQ_cut_hi
820 : type(auto_diff_real_2var_order1) :: logT_auto, logRho_auto, logQ_auto
821 : type(auto_diff_real_2var_order1) :: blend, blend_logT, blend_logRho, blend_logQ
822 : type(auto_diff_real_2var_order1) :: blend_cut, blend_logT_cut, blend_logRho_cut, blend_logQ_cut
823 :
824 : include 'formats'
825 :
826 210666 : ierr = 0
827 :
828 : ! auto diff
829 : ! var1: logRho
830 : ! var2: logT
831 :
832 210666 : logRho_auto% val = logRho
833 210666 : logRho_auto% d1val1 = 1
834 210666 : logRho_auto% d1val2 = 0
835 :
836 210666 : logT_auto% val = logT
837 210666 : logT_auto% d1val1 = 0
838 210666 : logT_auto% d1val2 = 1
839 :
840 210666 : logQ_auto = logRho_auto - 2d0*logT_auto + 12d0
841 :
842 : ! The FreeEOS region usually looks like
843 : !
844 : ! ________C________
845 : ! / |
846 : ! / D
847 : ! / __E__|
848 : ! B /
849 : ! / /
850 : ! / F
851 : ! / /
852 : ! / /
853 : ! / /
854 : ! / |
855 : ! / G
856 : ! /________A_______|
857 : !
858 : ! where blend A and C come from blend_logT,
859 : ! blend B comes from blend_logQ,
860 : ! blend D usually comes from PC/Skye,
861 : ! blend E comes from blend_logT_cut,
862 : ! blend F comes from blend_logQ_cut,
863 : ! blend G comes from blend_logRho_cut.
864 :
865 :
866 : ! logT blend
867 210666 : if (logT_auto < rq% logT_min_FreeEOS_lo) then
868 0 : blend_logT = 0d0
869 210666 : else if (logT_auto < rq% logT_min_FreeEOS_hi) then
870 6 : blend_logT = (logT_auto - rQ% logT_min_FreeEOS_lo) / (rq% logT_min_FreeEOS_hi - rq% logT_min_FreeEOS_lo)
871 210660 : else if (logT_auto < rq% logT_max_FreeEOS_lo) then
872 210660 : blend_logT = 1d0
873 0 : else if (logT_auto < rq% logT_max_FreeEOS_hi) then
874 0 : blend_logT = (logT_auto - rQ% logT_max_FreeEOS_hi) / (rq% logT_max_FreeEOS_lo - rq% logT_max_FreeEOS_hi)
875 : else
876 0 : blend_logT = 0
877 : end if
878 :
879 :
880 : ! logRho blend
881 210666 : if (logRho_auto < rq% logRho_min_FreeEOS_lo) then
882 0 : blend_logRho = 0d0
883 : else if (logRho_auto < rq% logRho_min_FreeEOS_lo) then
884 : blend_logRho = (logRho_auto - rQ% logRho_min_FreeEOS_lo) / (rq% logRho_min_FreeEOS_hi - rq% logRho_min_FreeEOS_lo)
885 210666 : else if (logRho_auto < rq% logRho_max_FreeEOS_lo) then
886 210666 : blend_logRho = 1d0
887 0 : else if (logRho_auto < rq% logRho_max_FreeEOS_hi) then
888 0 : blend_logRho = (logRho_auto - rQ% logRho_max_FreeEOS_hi) / (rq% logRho_max_FreeEOS_lo - rq% logRho_max_FreeEOS_hi)
889 : else
890 0 : blend_logRho = 0
891 : end if
892 :
893 :
894 : ! logQ blend
895 210666 : if (logQ_auto < rq% logQ_min_FreeEOS_lo) then
896 0 : blend_logQ = 0d0
897 210666 : else if (logQ_auto < rq% logQ_min_FreeEOS_hi) then
898 0 : blend_logQ = (logQ_auto - rQ% logQ_min_FreeEOS_lo) / (rq% logQ_min_FreeEOS_hi - rq% logQ_min_FreeEOS_lo)
899 210666 : else if (logQ_auto < rq% logQ_max_FreeEOS_lo) then
900 210666 : blend_logQ = 1d0
901 0 : else if (logQ_auto < rq% logQ_max_FreeEOS_hi) then
902 0 : blend_logQ = (logQ_auto - rQ% logQ_max_FreeEOS_hi) / (rq% logQ_max_FreeEOS_lo - rq% logQ_max_FreeEOS_hi)
903 : else
904 0 : blend_logQ = 0
905 : end if
906 :
907 :
908 : ! cut blend logRho
909 210666 : if (logRho_auto < rq% logRho_cut_FreeEOS_lo) then
910 51021 : blend_logRho_cut = 1d0
911 159645 : else if (logRho_auto < rq% logRho_cut_FreeEOS_hi) then
912 14245 : blend_logRho_cut = (logRho_auto - rQ% logRho_cut_FreeEOS_hi) / (rq% logRho_cut_FreeEOS_lo - rq% logRho_cut_FreeEOS_hi)
913 : else
914 145400 : blend_logRho_cut = 0d0
915 : end if
916 :
917 : ! cut blend logT
918 210666 : if (logT_auto < rq% logT_cut_FreeEOS_lo) then
919 110826 : blend_logT_cut = 0d0
920 99840 : else if (logT_auto < rq% logT_cut_FreeEOS_hi) then
921 3432 : blend_logT_cut = (logT_auto - rQ% logT_cut_FreeEOS_lo) / (rq% logT_cut_FreeEOS_hi - rq% logT_cut_FreeEOS_lo)
922 : else
923 96408 : blend_logT_cut = 1d0
924 : end if
925 :
926 : ! cut blend logQ
927 210666 : if (Z <= rq% logQ_cut_FreeEOS_lo_Z_max) then
928 210666 : logQ_cut_hi = rq% logQ_cut_lo_Z_FreeEOS_hi
929 210666 : logQ_cut_lo = rq% logQ_cut_lo_Z_FreeEOS_lo
930 : else
931 0 : logQ_cut_hi = rq% logQ_cut_hi_Z_FreeEOS_hi
932 0 : logQ_cut_lo = rq% logQ_cut_hi_Z_FreeEOS_lo
933 : end if
934 :
935 210666 : if (logQ_auto < logQ_cut_lo) then
936 210598 : blend_logQ_cut = 1d0
937 68 : else if (logQ_auto < logQ_cut_hi) then
938 10 : blend_logQ_cut = (logQ_auto - logQ_cut_hi) / (logQ_cut_lo - logQ_cut_hi)
939 : else
940 58 : blend_logQ_cut = 0d0
941 : end if
942 :
943 : ! combine cut blends
944 210666 : blend_cut = 0
945 210666 : if (blend_logT_cut == 0) then
946 110826 : if (blend_logQ_cut == 0) then
947 58 : blend_cut = blend_logRho_cut
948 110768 : else if (blend_logQ_cut == 1) then
949 110758 : blend_cut = 1d0
950 : else
951 10 : blend_cut = max(blend_logRho_cut, blend_logQ_cut)
952 : end if
953 99840 : elseif (blend_logT_cut == 1) then
954 96408 : blend_cut = 1d0
955 : else
956 3432 : if (blend_logQ_cut == 0) then
957 0 : blend_cut = blend_logT_cut
958 3432 : else if (blend_logQ_cut == 1) then
959 3432 : blend_cut = 1d0
960 : else
961 0 : blend_cut = max(blend_logT_cut, blend_logQ_cut)
962 : end if
963 : end if
964 :
965 : ! combine all blends
966 210666 : blend = blend_cut * blend_logT * blend_logRho * blend_logQ
967 :
968 : ! unpack auto_diff
969 210666 : alfa = 1d0 - blend% val
970 210666 : d_alfa_dlogRho = -blend% d1val1
971 210666 : d_alfa_dlogT = -blend% d1val2
972 :
973 210666 : end subroutine Get_FreeEOS_alfa
974 :
975 :
976 70 : subroutine get_opal_scvh_for_eosdt( &
977 : handle, dbg, Z, X, abar, zbar, &
978 70 : species, chem_id, net_iso, xa, &
979 : rho, logRho, T, logT, remaining_fraction, &
980 70 : res, d_dlnd, d_dlnT, d_dxa, &
981 : skip, ierr)
982 : integer, intent(in) :: handle
983 : logical, intent(in) :: dbg
984 : real(dp), intent(in) :: &
985 : Z, X, abar, zbar, remaining_fraction
986 : integer, intent(in) :: species
987 : integer, pointer :: chem_id(:), net_iso(:)
988 : real(dp), intent(in) :: xa(:)
989 : real(dp), intent(in) :: rho, logRho, T, logT
990 : real(dp), intent(inout), dimension(nv) :: &
991 : res, d_dlnd, d_dlnT
992 : real(dp), intent(inout), dimension(nv, species) :: d_dxa
993 : logical, intent(out) :: skip
994 : integer, intent(out) :: ierr
995 : call get1_for_eosdt( &
996 : handle, eosdt_OPAL_SCVH, dbg, &
997 : Z, X, abar, zbar, &
998 : species, chem_id, net_iso, xa, &
999 : rho, logRho, T, logT, remaining_fraction, &
1000 : res, d_dlnd, d_dlnT, d_dxa, &
1001 70 : skip, ierr)
1002 :
1003 : ! zero phase information
1004 280 : res(i_phase:i_latent_ddlnRho) = 0d0
1005 280 : d_dlnT(i_phase:i_latent_ddlnRho) = 0d0
1006 280 : d_dlnd(i_phase:i_latent_ddlnRho) = 0d0
1007 :
1008 : ! zero all components
1009 560 : res(i_frac:i_frac+num_eos_frac_results-1) = 0.0d0
1010 560 : d_dlnd(i_frac:i_frac+num_eos_frac_results-1) = 0.0d0
1011 560 : d_dlnT(i_frac:i_frac+num_eos_frac_results-1) = 0.0d0
1012 :
1013 : ! mark this one
1014 70 : res(i_frac_OPAL_SCVH) = 1.0d0
1015 :
1016 210666 : end subroutine get_opal_scvh_for_eosdt
1017 :
1018 :
1019 210602 : subroutine get_FreeEOS_for_eosdt( &
1020 : handle, dbg, Z, X, abar, zbar, &
1021 210602 : species, chem_id, net_iso, xa, &
1022 : rho, logRho, T, logT, remaining_fraction, &
1023 210602 : res, d_dlnd, d_dlnT, d_dxa, &
1024 : skip, ierr)
1025 : integer, intent(in) :: handle
1026 : logical, intent(in) :: dbg
1027 : real(dp), intent(in) :: &
1028 : Z, X, abar, zbar, remaining_fraction
1029 : integer, intent(in) :: species
1030 : integer, pointer :: chem_id(:), net_iso(:)
1031 : real(dp), intent(in) :: xa(:)
1032 : real(dp), intent(in) :: rho, logRho, T, logT
1033 : real(dp), intent(inout), dimension(nv) :: &
1034 : res, d_dlnd, d_dlnT
1035 : real(dp), intent(inout), dimension(nv, species) :: d_dxa
1036 : logical, intent(out) :: skip
1037 : integer, intent(out) :: ierr
1038 : call get1_for_eosdt( &
1039 : handle, eosdt_max_FreeEOS, dbg, Z, X, abar, zbar, &
1040 : species, chem_id, net_iso, xa, &
1041 : rho, logRho, T, logT, remaining_fraction, &
1042 : res, d_dlnd, d_dlnT, d_dxa, &
1043 210602 : skip, ierr)
1044 :
1045 : ! zero phase information
1046 842408 : res(i_phase:i_latent_ddlnRho) = 0d0
1047 842408 : d_dlnT(i_phase:i_latent_ddlnRho) = 0d0
1048 842408 : d_dlnd(i_phase:i_latent_ddlnRho) = 0d0
1049 :
1050 : ! zero all components
1051 1684816 : res(i_frac:i_frac+num_eos_frac_results-1) = 0.0d0
1052 1684816 : d_dlnd(i_frac:i_frac+num_eos_frac_results-1) = 0.0d0
1053 1684816 : d_dlnT(i_frac:i_frac+num_eos_frac_results-1) = 0.0d0
1054 :
1055 : ! mark this one
1056 210602 : res(i_frac_FreeEOS) = 1.0d0
1057 :
1058 210602 : end subroutine get_FreeEOS_for_eosdt
1059 :
1060 :
1061 70 : subroutine get_opal_scvh_alfa_and_partials( &
1062 : rq, logT, logRho, Z, alfa, d_alfa_dlogRho, d_alfa_dlogT, ierr)
1063 : type (EoS_General_Info), pointer :: rq
1064 : real(dp), intent(in) :: logT, logRho, Z
1065 : real(dp), intent(out) :: alfa, d_alfa_dlogRho, d_alfa_dlogT
1066 : integer, intent(out) :: ierr
1067 :
1068 : integer :: iregion
1069 : real(dp) :: logRho1_max, logRho1, logRho2, logRho5, logRho6, logRho7, &
1070 70 : logRho8, logT5, logT6, logT3, logT4
1071 70 : real(dp) :: logQ1, logQ2, logQ3, logQ4, logQmax, Z_all_HELM, Z_no_HELM
1072 70 : real(dp) :: beta, &
1073 70 : logT1, logT2, logT7, logT8, logRho3, logRho4
1074 70 : real(dp) :: logQ, A, B, dA_dlnT, dA_dlnRho, dB_dlnT, dB_dlnRho
1075 70 : real(dp) :: c_dx, c_dy, d_dx_dlogT, d_dx_dlogRho, d_dy_dlogT, d_dy_dlogRho
1076 : real(dp), parameter :: tiny = 1d-20
1077 :
1078 : include 'formats'
1079 :
1080 70 : logRho1_max = 3.71d0
1081 :
1082 70 : logQ1 = 5.69d0 ! SCVH full off for logQ > this
1083 70 : logQ2 = 5.68d0 ! must have logQ2 < logQ1
1084 70 : logQmax = rq% logQ_max_OPAL_SCVH ! 5.3
1085 70 : logQ3 = rq% logQ_min_OPAL_SCVH ! -8.0
1086 70 : logQ4 = rq% logQ_min_OPAL_SCVH ! -8.0
1087 :
1088 70 : logRho5 = rq% logRho_min_OPAL_SCVH_limit ! -14.299
1089 70 : logRho6 = logRho5 - 1d-3 ! -14.3
1090 70 : logRho7 = -14.90d0
1091 70 : logRho8 = -14.99d0
1092 :
1093 70 : logRho1 = rq% logRho1_OPAL_SCVH_limit ! 3.50
1094 70 : if (logRho1 > logRho1_max) then
1095 0 : write(*,*) 'sorry: value for logRho1_OPAL_SCVH_limit is too large. max allowed is ', &
1096 0 : logRho1_max
1097 0 : ierr = -1
1098 0 : return
1099 : end if
1100 70 : logRho2 = rq% logRho2_OPAL_SCVH_limit ! 3.48
1101 :
1102 70 : logT8 = rq% logT_low_all_HELM ! 2.2
1103 70 : logT7 = rq% logT_low_all_SCVH ! 2.3
1104 70 : logT6 = 4.890d0
1105 70 : logT5 = 4.899d0 ! problems with blend here so just jump
1106 70 : logT2 = rq% logT_all_OPAL ! 7.6
1107 70 : logT1 = rq% logT_all_HELM ! 7.7
1108 :
1109 70 : Z_all_HELM = rq% Z_all_HELM
1110 70 : Z_no_HELM = rq% Z_all_OPAL
1111 :
1112 70 : if (logT >= logT1) then ! just use other
1113 :
1114 0 : alfa = 1d0
1115 : beta = 0d0
1116 :
1117 : else
1118 :
1119 70 : logT3 = (logRho1 - logQ1 + 12d0)/2d0
1120 70 : logT4 = (logRho2 - logQ2 + 12d0)/2d0
1121 :
1122 70 : logRho3 = logQ1 + 2*logT7 - 12d0
1123 70 : logRho4 = logQ2 + 2*logT7 - 12d0
1124 :
1125 : if (.false.) then
1126 : write(*,'(A)')
1127 : write(*,1) 'logRho1', logRho1
1128 : write(*,1) 'logRho2', logRho2
1129 : write(*,1) 'logRho3', logRho3
1130 : write(*,1) 'logRho4', logRho4
1131 : write(*,1) 'logRho5', logRho5
1132 : write(*,1) 'logRho6', logRho6
1133 : write(*,1) 'logRho7', logRho7
1134 : write(*,1) 'logRho8', logRho8
1135 : write(*,'(A)')
1136 : write(*,1) 'logT1', logT1
1137 : write(*,1) 'logT2', logT2
1138 : write(*,1) 'logT3', logT3
1139 : write(*,1) 'logT4', logT4
1140 : write(*,1) 'logT5', logT5
1141 : write(*,1) 'logT6', logT6
1142 : write(*,1) 'logT7', logT7
1143 : write(*,1) 'logT8', logT8
1144 : write(*,'(A)')
1145 : write(*,1) 'logQ1', logQ1
1146 : write(*,1) 'logQ2', logQ2
1147 : write(*,'(A)')
1148 : call mesa_error(__FILE__,__LINE__,'eosdt_eval')
1149 : end if
1150 :
1151 : ! check validity of Rho's and T's for region boundaries
1152 : if (logRho1 <= logRho2 .or. logRho2 <= logRho3 .or. &
1153 : logRho3 <= logRho4 .or. logRho4 <= logRho5 .or. &
1154 : logRho5 <= logRho6 .or. logRho6 <= logRho7 .or. &
1155 : logRho7 <= logRho8 .or. &
1156 70 : logT1 <= logT2 .or. logT2 <= logT3 .or. logT3 <= logT4 .or. &
1157 : logT7 <= logT8) then
1158 0 : write(*,'(A)')
1159 0 : write(*,'(A)')
1160 0 : write(*,'(A)')
1161 0 : write(*,'(a)') 'must have strictly decreasing values for eos logT + logRho region boundaries'
1162 0 : write(*,'(A)')
1163 0 : write(*,1) 'logRho1', logRho1
1164 0 : write(*,1) 'logRho2', logRho2
1165 0 : write(*,1) 'logRho3', logRho3
1166 0 : write(*,1) 'logRho4', logRho4
1167 0 : write(*,1) 'logRho5', logRho5
1168 0 : write(*,1) 'logRho6', logRho6
1169 0 : write(*,1) 'logRho7', logRho7
1170 0 : write(*,1) 'logRho8', logRho8
1171 0 : write(*,'(A)')
1172 0 : write(*,1) 'logT1', logT1
1173 0 : write(*,1) 'logT2', logT2
1174 0 : write(*,1) 'logT3', logT3
1175 0 : write(*,1) 'logT4', logT4
1176 0 : write(*,1) 'logT5', logT5
1177 0 : write(*,1) 'logT6', logT6
1178 0 : write(*,1) 'logT7', logT7
1179 0 : write(*,1) 'logT8', logT8
1180 0 : write(*,'(A)')
1181 0 : write(*,1) 'logQ1', logQ1
1182 0 : write(*,1) 'logQ2', logQ2
1183 0 : write(*,'(A)')
1184 0 : write(*,'(A)')
1185 0 : if (logT3 <= logT4) then
1186 0 : write(*,'(a)') 'must have logRho1 > logRho2 + logQ1 - logQ2'
1187 0 : write(*,1) 'must have logRho1 > ', logRho2 + logQ1 - logQ2
1188 0 : write(*,1) 'logRho1', logRho1
1189 0 : write(*,'(a)') 'logRho1_OPAL_SCVH_limit sets logRho1'
1190 0 : write(*,'(a)') 'logRho2_OPAL_SCVH_limit sets logRho2'
1191 0 : write(*,1) 'max allowed logRho1 is', logRho1_max
1192 : end if
1193 0 : write(*,'(A)')
1194 0 : ierr = -1
1195 0 : return
1196 : end if
1197 :
1198 70 : call determine_region_opal_scvh
1199 :
1200 70 : call set_alfa_and_partials
1201 70 : if (ierr /= 0) return
1202 :
1203 : end if
1204 :
1205 :
1206 : contains
1207 :
1208 :
1209 70 : subroutine determine_region_opal_scvh
1210 : logical, parameter :: dbg = .false.
1211 70 : real(dp) :: logRho_hi, logRho_lo, d_logRho_dlogT, &
1212 70 : d_alfa_dlogQ, dlogQ_dlogRho, dlogQ_dlogT, Z_all_HELM
1213 :
1214 : include 'formats'
1215 :
1216 70 : logQ = logRho - 2d0*logT + 12d0
1217 70 : d_dx_dlogRho=0d0
1218 70 : d_dy_dlogT=0d0
1219 :
1220 : ! in high-Z fall back to HELM
1221 70 : if (Z >= rq% Z_all_HELM) then
1222 0 : iregion = use_none
1223 : if (dbg) then
1224 : write(*,1) 'iregion = use_none'
1225 : write(*,1) 'Z Z_all_HELM', Z, rq% Z_all_HELM
1226 : stop
1227 : end if
1228 : return
1229 : end if
1230 :
1231 : ! blends in T/Rho
1232 :
1233 : if (logT >= logT1 .or. logT <= logT8 .or. logRho >= logRho1 .or. &
1234 70 : logQ <= logQ4 .or. logQ >= logQmax .or. &
1235 : (logRho <= logRho6 .and. logT <= logT6)) then
1236 : if (dbg) then
1237 : write(*,*) 'logT >= logT1', logT >= logT1
1238 : write(*,*) 'logT <= logT8', logT <= logT8
1239 : write(*,*) 'logRho >= logRho1', logRho >= logRho1
1240 : write(*,*) 'logQ <= logQ4', logQ <= logQ4, logQ, logQ4
1241 : write(*,*) 'logQ >= logQmax', logQ >= logQmax
1242 : write(*,*) 'logRho <= logRho6 .and. logT <= logT6', logRho <= logRho6 .and. logT <= logT6
1243 : write(*,1) 'iregion = use_none 1 logT logT5 logT6', logT, logT5, logT6
1244 : end if
1245 0 : iregion = use_none
1246 :
1247 70 : else if (logQ <= logQ3 .and. logT >= logT5) then ! blend in Q
1248 0 : d_alfa_dlogQ = 1d0/(logQ4 - logQ3)
1249 0 : alfa = (logQ - logQ3)*d_alfa_dlogQ
1250 0 : dlogQ_dlogRho = 1d0
1251 0 : dlogQ_dlogT = -2d0
1252 0 : d_dx_dlogRho = d_alfa_dlogQ*dlogQ_dlogRho
1253 0 : d_dy_dlogT = d_alfa_dlogQ*dlogQ_dlogT
1254 0 : c_dx = alfa
1255 : if (dbg) then
1256 : write(*,*) 'iregion = blend_diagonal'
1257 : write(*,1) 'logQ3', logQ3
1258 : write(*,1) 'logQ', logQ
1259 : write(*,1) 'logQ4', logQ4
1260 : write(*,1) 'd_alfa_dlogQ', d_alfa_dlogQ
1261 : write(*,1) 'c_dx', c_dx
1262 : write(*,1) 'd_dx_dlogRho', d_dx_dlogRho
1263 : write(*,1) 'd_dy_dlogT', d_dy_dlogT
1264 : end if
1265 0 : iregion = blend_diagonal
1266 :
1267 70 : else if (logT >= logT2) then
1268 : if (dbg) write(*,*) 'logT >= logT2', logT, logT2
1269 0 : if (logT1 - logT2 < 0.01d0) then
1270 : d_dy_dlogT = 0d0
1271 : ! bad blend partials cause problems for 150M_z1m4_pre_ms_to_collapse
1272 : ! have tried to fix, but failed. hence this awful workaround.
1273 : else
1274 0 : d_dy_dlogT = 1/(logT1 - logT2)
1275 : end if
1276 0 : c_dy = (logT - logT2)*d_dy_dlogT
1277 0 : if (logRho > logRho2) then
1278 : if (dbg) write(*,*) 'logRho > logRho2', logRho, logRho2
1279 0 : d_dx_dlogRho = 1/(logRho1 - logRho2)
1280 0 : c_dx = (logRho - logRho2)*d_dx_dlogRho
1281 : if (dbg) write(*,*) 'iregion = blend_corner_out'
1282 0 : iregion = blend_corner_out
1283 : else ! logRho <= logRho2
1284 : if (dbg) write(*,*) 'logRho <= logRho2', logRho, logRho2
1285 : if (dbg) write(*,*) 'iregion = blend_in_y'
1286 0 : iregion = blend_in_y
1287 : end if
1288 :
1289 70 : else if (logT >= logT3) then ! NOTE: this assumes logT3 > logT4
1290 : if (dbg) write(*,*) 'logT >= logT3', logT, logT3
1291 8 : if (logRho > logRho2) then
1292 : if (dbg) write(*,*) 'logRho > logRho2', logRho, logRho2
1293 0 : d_dx_dlogRho = 1/(logRho1 - logRho2)
1294 0 : c_dx = (logRho - logRho2)*d_dx_dlogRho
1295 : if (dbg) write(*,*) 'iregion = blend_in_x'
1296 0 : iregion = blend_in_x
1297 : else
1298 : if (dbg) write(*,*) 'logRho <= logRho2', logRho, logRho2
1299 : if (dbg) write(*,*) 'iregion = use_all'
1300 8 : iregion = use_all
1301 : end if
1302 :
1303 62 : else if (logT >= logT4) then
1304 : if (dbg) write(*,*) 'logT >= logT4', logT, logT4
1305 0 : logRho_hi = logQ1 + 2*logT - 12
1306 0 : if (logRho >= logRho_hi) then
1307 : if (dbg) write(*,*) 'logRho >= logRho_hi', logRho, logRho_hi
1308 : if (dbg) write(*,*) 'iregion = use_none 2'
1309 0 : iregion = use_none
1310 0 : else if (logRho > logRho2) then
1311 : if (dbg) write(*,*) 'logRho > logRho2', logRho, logRho2
1312 0 : d_dx_dlogRho = 1/(logRho_hi - logRho2)
1313 0 : c_dx = (logRho - logRho2)*d_dx_dlogRho
1314 : if (dbg) write(*,*) 'iregion = blend_in_x'
1315 0 : iregion = blend_in_x
1316 : else ! logRho <= logRho2
1317 : if (dbg) write(*,*) 'logRho <= logRho2', logRho, logRho2
1318 : if (dbg) write(*,*) 'iregion = use_all'
1319 0 : iregion = use_all
1320 : end if
1321 :
1322 62 : else if (logRho > logRho4) then
1323 : if (dbg) write(*,*) 'logRho > logRho4', logRho, logRho4
1324 8 : if (logT > logT7) then
1325 8 : A = ((logQ1+2*logT4-12) - logRho3)/(logT4-logT7)
1326 8 : logRho_hi = logRho3 + (logT-logT7)*A
1327 8 : B = (logRho2-logRho4)/(logT4-logT7)
1328 8 : logRho_lo = logRho4 + (logT-logT7)*B
1329 8 : if (logRho >= logRho_hi) then
1330 : if (dbg) write(*,*) 'logRho >= logRho_hi', logRho, logRho_hi
1331 : if (dbg) write(*,*) 'iregion = use_none 3'
1332 0 : iregion = use_none
1333 8 : else if (logRho >= logRho_lo) then
1334 : if (dbg) write(*,*) 'logRho >= logRho_lo', logRho, logRho_lo
1335 0 : c_dx = (logRho - logRho_lo)/(logRho_hi - logRho_lo)
1336 0 : d_dx_dlogRho = 1/(logRho3 - logRho4 + (A - B)*(logT - logT7))
1337 : if (dbg) write(*,*) 'iregion = blend_in_x'
1338 0 : iregion = blend_in_x
1339 : else ! logRho < logRho_lo
1340 : if (dbg) write(*,*) 'logRho < logRho_lo', logRho, logRho_lo
1341 : if (dbg) write(*,*) 'iregion = use_all'
1342 8 : iregion = use_all
1343 : end if
1344 : else ! logT is > logT8
1345 : if (dbg) write(*,*) 'logT > logT8', logT, logT8
1346 0 : if (logRho > logRho3) then
1347 : if (dbg) write(*,*) 'logRho > logRho3', logRho, logRho3
1348 : if (dbg) write(*,*) 'iregion = use_none 4'
1349 0 : iregion = use_none
1350 : else ! logRho is > logRho4
1351 : if (dbg) write(*,*) 'logRho <= logRho3', logRho, logRho3
1352 0 : d_dx_dlogRho = 1/(logRho3 - logRho4)
1353 0 : c_dx = (logRho - logRho4)*d_dx_dlogRho
1354 0 : d_dy_dlogT = 1/(logT8 - logT7)
1355 0 : c_dy = (logT - logT7)*d_dy_dlogT
1356 : if (dbg) write(*,*) 'iregion = blend_corner_out'
1357 0 : iregion = blend_corner_out
1358 : end if
1359 : end if
1360 :
1361 54 : else if (logRho >= logRho5 .or. logT > logT5) then
1362 : if (dbg) write(*,*) 'iregion = use_all'
1363 54 : iregion = use_all
1364 :
1365 0 : else if (logT >= logT6) then
1366 0 : if (logRho <= logRho6) then
1367 0 : d_dy_dlogT = 1/(logT6 - logT5)
1368 0 : c_dy = (logT - logT5)*d_dy_dlogT
1369 : if (dbg) write(*,*) 'iregion = blend_in_y'
1370 0 : iregion = blend_in_y
1371 : else
1372 0 : d_dx_dlogRho = 1/(logRho5 - logRho6)
1373 0 : c_dx = (logRho - logRho6)*d_dx_dlogRho
1374 0 : d_dy_dlogT = 1/(logT5 - logT6)
1375 0 : c_dy = (logT - logT6)*d_dy_dlogT
1376 : if (dbg) write(*,*) 'iregion = blend_corner_in'
1377 0 : iregion = blend_corner_in
1378 : end if
1379 :
1380 : else
1381 : if (dbg) write(*,*) 'logRho > logRho6', logRho, logRho6
1382 0 : d_dx_dlogRho = 1/(logRho6 - logRho5)
1383 0 : c_dx = (logRho - logRho5)*d_dx_dlogRho
1384 : if (dbg) write(*,*) 'iregion = blend_in_x'
1385 0 : iregion = blend_in_x
1386 : end if
1387 :
1388 : if (dbg) call mesa_error(__FILE__,__LINE__,'determine_region')
1389 :
1390 : end subroutine determine_region_opal_scvh
1391 :
1392 :
1393 70 : subroutine set_alfa_and_partials ! alfa = fraction other
1394 : logical, parameter :: dbg = .false.
1395 :
1396 70 : real(dp) :: zfactor
1397 :
1398 : include 'formats'
1399 :
1400 70 : d_alfa_dlogT = 0d0
1401 70 : d_alfa_dlogRho = 0
1402 :
1403 70 : if (iregion == use_none .or. Z >= Z_all_HELM) then
1404 : if (dbg) write(*,*) 'iregion == use_none'
1405 0 : alfa = 1
1406 : else if (iregion == use_all) then
1407 : if (dbg) write(*,*) 'iregion == use_all'
1408 70 : alfa = 0
1409 : else if (iregion == blend_in_y) then
1410 : if (dbg) write(*,*) 'iregion == blend_in_y'
1411 0 : alfa = c_dy
1412 0 : d_alfa_dlogT = d_dy_dlogT
1413 : else if (iregion == blend_in_x) then
1414 : if (dbg) write(*,*) 'iregion == blend_in_x'
1415 0 : alfa = c_dx
1416 0 : d_alfa_dlogRho = d_dx_dlogRho
1417 : else if (iregion == blend_diagonal) then
1418 : if (dbg) write(*,*) 'iregion == blend_diagonal'
1419 0 : alfa = c_dx
1420 0 : d_alfa_dlogRho = d_dx_dlogRho
1421 0 : d_alfa_dlogT = d_dy_dlogT
1422 : else if (iregion == blend_corner_out) then
1423 : if (dbg) write(*,*) 'iregion == blend_corner_out'
1424 0 : alfa = sqrt(c_dx*c_dx + c_dy*c_dy)
1425 0 : if (alfa >= 1d0) then
1426 0 : alfa = 1
1427 0 : else if (alfa < 1d-10) then
1428 0 : alfa = 0
1429 : else
1430 0 : d_alfa_dlogT = c_dy*d_dy_dlogT/alfa
1431 0 : d_alfa_dlogRho = c_dx*d_dx_dlogRho/alfa
1432 : end if
1433 : else if (iregion == blend_corner_in) then
1434 : if (dbg) write(*,*) 'iregion == blend_corner_in'
1435 0 : beta = sqrt(c_dx*c_dx + c_dy*c_dy)
1436 0 : alfa = 1d0 - beta
1437 0 : if (alfa >= 1d0) then
1438 0 : alfa = 1d0
1439 0 : else if (alfa < 1d-10) then
1440 0 : alfa = 0
1441 : else
1442 0 : d_alfa_dlogT = -c_dy*d_dy_dlogT/beta
1443 0 : d_alfa_dlogRho = -c_dx*d_dx_dlogRho/beta
1444 : end if
1445 : else
1446 0 : ierr = -1
1447 0 : return
1448 : end if
1449 :
1450 70 : if (Z > Z_no_HELM .and. Z < Z_all_HELM .and. alfa < 1d0) then
1451 : ! reduce alfa to reduce the HELM fraction
1452 0 : zfactor = (Z - Z_no_HELM)/(Z_all_HELM - Z_no_HELM)
1453 0 : alfa = alfa*zfactor
1454 0 : d_alfa_dlogRho = d_alfa_dlogRho*zfactor
1455 0 : d_alfa_dlogT = d_alfa_dlogT*zfactor
1456 : end if
1457 :
1458 : end subroutine set_alfa_and_partials
1459 :
1460 :
1461 : end subroutine get_opal_scvh_alfa_and_partials
1462 :
1463 :
1464 1145158 : subroutine combine_for_eosdt( &
1465 : get_1st, get_2nd, remaining_fraction, &
1466 : alfa_in, d_alfa_dlogT_in, d_alfa_dlogRho_in, &
1467 : rq, dbg, Z, X, abar, zbar, &
1468 1145158 : species, chem_id, net_iso, xa, &
1469 : rho, logRho, T, logT, &
1470 1145158 : res, d_dlnd, d_dlnT, d_dxa, &
1471 : skip, ierr)
1472 : use eosdt_support, only : Do_Blend
1473 : procedure (get_values_for_eosdt_interface), pointer :: get_1st, get_2nd
1474 : type (EoS_General_Info), pointer :: rq
1475 : logical, intent(in) :: dbg
1476 : real(dp), intent(in) :: Z, X, abar, zbar, &
1477 : alfa_in, d_alfa_dlogT_in, d_alfa_dlogRho_in, remaining_fraction
1478 : integer, intent(in) :: species
1479 : integer, pointer :: chem_id(:), net_iso(:)
1480 : real(dp), intent(in) :: xa(:)
1481 : real(dp), intent(in) :: rho, logRho, T, logT
1482 : real(dp), intent(inout), dimension(nv) :: res, d_dlnd, d_dlnT
1483 : real(dp), intent(inout), dimension(nv, species) :: d_dxa
1484 : logical, intent(out) :: skip
1485 : integer, intent(out) :: ierr
1486 :
1487 : real(dp), dimension(nv) :: &
1488 179789806 : res_1, d_dlnd_1, d_dlnT_1, res_2, d_dlnd_2, d_dlnT_2
1489 1145158 : real(dp), dimension(:,:), allocatable :: d_dxa_1, d_dxa_2
1490 : real(dp) :: alfa, d_alfa_dlogT, d_alfa_dlogRho
1491 : logical :: skip_1st, skip_2nd
1492 : logical, parameter :: linear_blend = .false.
1493 :
1494 : include 'formats'
1495 :
1496 1145158 : ierr = 0
1497 1145158 : skip = .false.
1498 :
1499 1145158 : allocate(d_dxa_1(nv, species), d_dxa_2(nv, species))
1500 :
1501 1145158 : alfa = alfa_in
1502 1145158 : d_alfa_dlogT = d_alfa_dlogT_in
1503 1145158 : d_alfa_dlogRho = d_alfa_dlogRho_in
1504 :
1505 1145158 : if (alfa == 0d0) then ! pure 1st
1506 : call get_1st(rq% handle, dbg, &
1507 : Z, X, abar, zbar, &
1508 : species, chem_id, net_iso, xa, &
1509 : rho, logRho, T, logT, remaining_fraction, &
1510 : res, d_dlnd, d_dlnT, d_dxa, &
1511 241252 : skip_1st, ierr)
1512 241252 : if (ierr /= 0) then
1513 2260436 : if (.not. rq% okay_to_convert_ierr_to_skip) return
1514 0 : if (dbg) write(*,*) 'ierr => skip 1st in combine_for_eosdt'
1515 0 : ierr = 0; skip_1st = .true.
1516 : end if
1517 241252 : if (skip_1st) then ! switch to pure 2nd
1518 0 : alfa = 1d0; d_alfa_dlogT = 0d0; d_alfa_dlogRho = 0d0
1519 : else
1520 : return
1521 : end if
1522 : end if
1523 :
1524 903906 : if (alfa < 1d0) then ! some of 1st
1525 : call get_1st(rq% handle, dbg, &
1526 : Z, X, abar, zbar, &
1527 : species, chem_id, net_iso, xa, &
1528 : rho, logRho, T, logT, remaining_fraction, &
1529 : res_2, d_dlnd_2, d_dlnT_2, d_dxa_2, &
1530 14940 : skip_1st, ierr)
1531 14940 : if (ierr /= 0) then
1532 0 : if (.not. rq% okay_to_convert_ierr_to_skip) return
1533 0 : if (dbg) write(*,*) 'ierr => skip 1st in combine_for_eosdt'
1534 0 : ierr = 0; skip_1st = .true.
1535 : end if
1536 14940 : if (skip_1st) then ! switch to pure 2nd
1537 0 : alfa = 1d0; d_alfa_dlogT = 0d0; d_alfa_dlogRho = 0d0
1538 : end if
1539 : end if
1540 :
1541 903906 : if (alfa == 1d0) then ! no 1st
1542 : call get_2nd(rq% handle, dbg, &
1543 : Z, X, abar, zbar, &
1544 : species, chem_id, net_iso, xa, &
1545 : Rho, logRho, T, logT, remaining_fraction, &
1546 : res, d_dlnd, d_dlnT, d_dxa, &
1547 888966 : skip_2nd, ierr)
1548 888966 : if (ierr /= 0) then
1549 0 : if (.not. rq% okay_to_convert_ierr_to_skip) return
1550 0 : if (dbg) write(*,*) 'ierr => skip 2nd in combine_for_eosdt'
1551 0 : ierr = 0; skip_2nd = .true.
1552 : end if
1553 888966 : if (skip_2nd) skip = .true.
1554 888966 : return
1555 : end if
1556 :
1557 : ! blend 1st and 2nd
1558 :
1559 : call get_2nd( &
1560 : rq% handle, dbg, Z, X, abar, zbar, &
1561 : species, chem_id, net_iso, xa, &
1562 : Rho, logRho, T, logT, remaining_fraction, &
1563 : res_1, d_dlnd_1, d_dlnT_1, d_dxa_1, &
1564 14940 : skip_2nd, ierr)
1565 14940 : if (ierr /= 0) then
1566 0 : if (.not. rq% okay_to_convert_ierr_to_skip) return
1567 0 : if (dbg) write(*,*) 'ierr => skip 2nd in combine_for_eosdt'
1568 0 : ierr = 0; skip_2nd = .true.
1569 : end if
1570 14940 : if (skip_2nd) then
1571 0 : skip = .true.
1572 0 : return
1573 : end if
1574 : call Do_Blend( &
1575 : rq, species, Rho, logRho, T, logT, &
1576 : alfa, d_alfa_dlogT, d_alfa_dlogRho, linear_blend, &
1577 : res_1, d_dlnd_1, d_dlnT_1, d_dxa_1, &
1578 : res_2, d_dlnd_2, d_dlnT_2, d_dxa_2, &
1579 14940 : res, d_dlnd, d_dlnT, d_dxa)
1580 :
1581 3405594 : end subroutine combine_for_eosdt
1582 :
1583 :
1584 210672 : subroutine get1_for_eosdt( &
1585 : handle, which_eosdt, dbg, Z, X, abar, zbar, &
1586 : species, chem_id, net_iso, xa, &
1587 : rho, logRho, T, logT, remaining_fraction, &
1588 210672 : res, d_dlnd, d_dlnT, d_dxa, &
1589 : skip, ierr)
1590 1145158 : use chem_def, only: chem_isos
1591 : integer, intent(in) :: handle
1592 : integer, intent(in) :: which_eosdt
1593 : logical, intent(in) :: dbg
1594 : real(dp), intent(in) :: &
1595 : Z, X, abar, zbar, remaining_fraction
1596 : integer, intent(in) :: species
1597 : integer, pointer :: chem_id(:), net_iso(:)
1598 : real(dp), intent(in) :: xa(:)
1599 : real(dp), intent(in) :: rho, logRho, T, logT
1600 : real(dp), intent(inout), dimension(nv) :: &
1601 : res, d_dlnd, d_dlnT
1602 : real(dp), intent(inout), dimension(nv, species) :: d_dxa
1603 11376288 : real(dp), dimension(nv) :: d_dX, d_dZ
1604 : logical, intent(out) :: skip
1605 : integer, intent(out) :: ierr
1606 : type (EoS_General_Info), pointer :: rq
1607 : type (DT_xz_Info), pointer :: xz
1608 : integer :: i
1609 210672 : rq => eos_handles(handle)
1610 210672 : if (which_eosdt == eosdt_max_FreeEOS) then
1611 210602 : xz => FreeEOS_xz_struct
1612 : else
1613 70 : xz => eosDT_xz_struct
1614 : end if
1615 : call Get1_eosdt_Results( &
1616 : rq, which_eosdt, xz, Z, X, Rho, logRho, T, logT, &
1617 210672 : res, d_dlnd, d_dlnT, d_dX, d_dZ, ierr)
1618 1877236 : do i=1,species
1619 210672 : select case(chem_isos% Z(chem_id(i))) ! charge
1620 : case (1) ! X
1621 5688144 : d_dxa(:,i) = d_dX
1622 : case (2) ! Y
1623 10868202 : d_dxa(:,i) = 0
1624 : case default ! Z
1625 29054080 : d_dxa(:,i) = d_dZ
1626 : end select
1627 : end do
1628 210672 : skip = .false.
1629 210672 : end subroutine get1_for_eosdt
1630 :
1631 :
1632 210672 : subroutine Get1_eosdt_Results( & ! blend in Z
1633 : rq, which_eosdt, xz, Z, X, Rho, logRho, T, logT, &
1634 : res, dlnd, dlnT, dX, dZ, ierr)
1635 210672 : use chem_def
1636 : type (EoS_General_Info), pointer :: rq
1637 : integer, intent(in) :: which_eosdt
1638 : type (DT_xz_Info), pointer :: xz
1639 : real(dp), intent(in) :: Z, X, Rho, logRho, T, logT
1640 : real(dp), intent(inout), dimension(nv) :: res, dlnd, dlnT, dX, dZ
1641 : integer, intent(out) :: ierr
1642 :
1643 45715824 : real(dp), dimension(nv, 2) :: res_zx, dlnd_zx, dlnT_zx, dX_zx
1644 1053360 : real(dp) :: denom, c(2), dcdZ(2), tiny
1645 :
1646 : integer :: iz, j, ci
1647 :
1648 : include 'formats'
1649 :
1650 210672 : ierr = 0
1651 210672 : tiny = rq% tiny_fuzz
1652 :
1653 210672 : if (xz% nZs < 3) then
1654 0 : write(*, *) 'error: Get1_eosdt_Results assumes nZs >= 3'
1655 0 : call mesa_error(__FILE__,__LINE__)
1656 : end if
1657 :
1658 210672 : if (xz% Zs(1) /= 0) then
1659 0 : write(*, *) 'error: Get1_eosdt_Results assumes eos_Zs(1) == 0'
1660 0 : call mesa_error(__FILE__,__LINE__)
1661 : end if
1662 :
1663 210672 : if (abs(xz% Zs(1) - 2*xz% Zs(2) + xz% Zs(3)) > tiny) then
1664 0 : write(*, *) 'error: Get1_eosdt_Results assumes equal spaced Zs(1:3)'
1665 0 : call mesa_error(__FILE__,__LINE__)
1666 : end if
1667 :
1668 210672 : if (Z <= max(1d-20,xz% Zs(1))) then
1669 : call Get1_eosdt_for_X( &
1670 : rq, which_eosdt, xz, 1, X, &
1671 : Rho, logRho, T, logT, &
1672 12 : res, dlnd, dlnT, dX, ierr)
1673 12 : dZ = 0
1674 12 : return
1675 : end if
1676 :
1677 : ! zero these for now
1678 1895940 : res_zx(i_phase:i_latent_ddlnRho,:) = 0d0
1679 3581220 : res_zx(i_frac:i_frac+num_eos_frac_results-1,:) = 0d0
1680 :
1681 1895940 : dlnd_zx(i_phase:i_latent_ddlnRho,:) = 0d0
1682 3581220 : dlnd_zx(i_frac:i_frac+num_eos_frac_results-1,:) = 0d0
1683 :
1684 1895940 : dlnT_zx(i_phase:i_latent_ddlnRho,:) = 0d0
1685 3581220 : dlnT_zx(i_frac:i_frac+num_eos_frac_results-1,:) = 0d0
1686 :
1687 210660 : if (Z >= xz% Zs(xz% nZs)) then
1688 : call Get1_eosdt_for_X( &
1689 : rq, which_eosdt, xz, xz% nZs, X, &
1690 : Rho, logRho, T, logT, &
1691 0 : res, dlnd, dlnT, dX, ierr)
1692 0 : dZ = 0
1693 0 : return
1694 : end if
1695 :
1696 317068 : do iz = 2, xz% nZs
1697 317068 : if (Z < xz% Zs(iz)) then
1698 210660 : call do_interp2(iz-1,iz,ierr)
1699 210660 : if (ierr /= 0) return
1700 : exit
1701 : end if
1702 : end do
1703 :
1704 5898492 : do j=1,nv
1705 :
1706 5477160 : res(j) = c(1)*res_zx(j,1) + c(2)*res_zx(j,2)
1707 :
1708 : dlnd(j) = &
1709 5477160 : c(1)*dlnd_zx(j,1) + c(2)*dlnd_zx(j,2)
1710 :
1711 : dlnT(j) = &
1712 5477160 : c(1)*dlnT_zx(j,1) + c(2)*dlnT_zx(j,2)
1713 :
1714 : dX(j) = &
1715 5477160 : c(1)*dX_zx(j,1) + c(2)*dX_zx(j,2)
1716 :
1717 : dZ(j) = &
1718 5687820 : dcdZ(1)*res_zx(j,1) + dcdZ(2)*res_zx(j,2)
1719 :
1720 : end do
1721 :
1722 : contains
1723 :
1724 210660 : subroutine do_interp2(iz1, iz2, ierr)
1725 : integer, intent(in) :: iz1, iz2
1726 : integer, intent(out) :: ierr
1727 210660 : real(dp) :: Z1, Z2
1728 : include 'formats'
1729 : ierr = 0
1730 210660 : Z1 = xz% Zs(iz1)
1731 210660 : Z2 = xz% Zs(iz2)
1732 210660 : c(2) = (Z - Z1) / (Z2 - Z1)
1733 210660 : c(1) = 1d0 - c(2)
1734 210660 : dcdZ(2) = 1d0/(Z2 - Z1)
1735 210660 : dcdZ(1) = -dcdZ(2)
1736 : call Get1_eosdt_for_X( &
1737 : rq, which_eosdt, xz, iz1, X, Rho, logRho, T, logT, &
1738 : res_zx(:,1), dlnd_zx(:,1), dlnT_zx(:,1), dX_zx(:,1), &
1739 210660 : ierr)
1740 210660 : if (ierr /= 0) return
1741 : call Get1_eosdt_for_X( &
1742 : rq, which_eosdt, xz, iz2, X, Rho, logRho, T, logT, &
1743 : res_zx(:,2), dlnd_zx(:,2), dlnT_zx(:,2), dX_zx(:,2), &
1744 210660 : ierr)
1745 : if (ierr /= 0) return
1746 210672 : end subroutine do_interp2
1747 :
1748 : end subroutine Get1_eosdt_Results
1749 :
1750 :
1751 421332 : subroutine Get1_eosdt_for_X( &
1752 : rq, which_eosdt, xz, iz, X, Rho, logRho, T, logT, &
1753 : res, dlnd, dlnT, d_dX, ierr)
1754 : type (EoS_General_Info), pointer :: rq
1755 : integer, intent(in) :: which_eosdt
1756 : type (DT_xz_Info), pointer :: xz
1757 : integer, intent(in) :: iz ! the index in eos_Zs
1758 : real(dp), intent(in) :: X, Rho, logRho, T, logT
1759 : real(dp), intent(inout), dimension(nv) :: &
1760 : res, dlnd, dlnT, d_dX
1761 : integer, intent(out) :: ierr
1762 :
1763 : real(dp), dimension(nv, 4) :: &
1764 137354232 : res_zx, dlnd_zx, dlnT_zx
1765 2527992 : real(dp) :: dX, dX1, dX2, dX3, c(4), dcdX(4), denom, delX, coef, dcoef_dX, alfa, beta, dalfa_dX, dbeta_dX, tiny
1766 : character (len=256) :: message
1767 : integer :: ix, ix_lo, ix_hi, j, num_Xs
1768 : logical, parameter :: dbg_for_X = dbg ! .or. .true.
1769 : logical :: what_we_use_is_equal_spaced
1770 :
1771 : include 'formats'
1772 :
1773 421332 : ierr = 0
1774 421332 : tiny = rq% tiny_fuzz
1775 :
1776 421332 : num_Xs = xz% nXs_for_Z(iz)
1777 :
1778 421332 : if (xz% Xs_for_Z(1,iz) /= 0d0) then
1779 0 : write(*, *) 'error: Get1_eosdt_for_X assumes xz% nXs_for_Z(1) == 0'
1780 0 : call mesa_error(__FILE__,__LINE__)
1781 : end if
1782 :
1783 421332 : if (X < tiny .or. num_Xs == 1) then
1784 : call Get1_eosdt_XTable_Results( &
1785 : rq, which_eosdt, 1, iz, Rho, logRho, T, logT, &
1786 10 : res, dlnd, dlnT, ierr)
1787 10 : d_dX = 0
1788 16 : return
1789 : end if
1790 :
1791 421322 : if (X >= xz% Xs_for_Z(num_Xs,iz)) then
1792 :
1793 : call Get1_eosdt_XTable_Results( &
1794 : rq, which_eosdt, num_Xs, iz, Rho, logRho, T, logT, &
1795 6 : res, dlnd, dlnT, ierr)
1796 6 : d_dX = 0
1797 :
1798 6 : if (is_bad(res(i_lnS))) then
1799 0 : ierr = -1
1800 0 : if (.not. stop_for_is_bad) return
1801 : write(*,1) 'res(i_lnS), logRho, logT', res(i_lnS), logRho, logT
1802 : call mesa_error(__FILE__,__LINE__,'Get1_eosdt_for_X num_Xs')
1803 : end if
1804 :
1805 : return
1806 : end if
1807 :
1808 421316 : if (rq% eosDT_use_linear_interp_for_X .or. num_Xs == 2) then
1809 0 : call do_linear
1810 0 : return
1811 : end if
1812 :
1813 421316 : ix_hi = -1
1814 421316 : if (X <= xz% Xs_for_Z(2,iz)) then
1815 0 : ix_lo = 1; ix_hi = 3
1816 421316 : else if (X >= xz% Xs_for_Z(num_Xs-1,iz)) then
1817 76 : ix_lo = num_Xs-2; ix_hi = num_Xs
1818 : else
1819 2527300 : do ix = 3, num_Xs-1
1820 2527300 : if (X <= xz% Xs_for_Z(ix,iz)) then
1821 421240 : ix_lo = ix-2; ix_hi = ix+1; exit
1822 : end if
1823 : end do
1824 : end if
1825 :
1826 421316 : if (ix_hi < 0) then
1827 0 : write(*, *) 'X', X
1828 0 : write(*, *) 'ix_lo', ix_lo
1829 0 : write(*, *) 'ix_hi', ix_hi
1830 0 : write(*, *) 'error: Get1_eosdt_for_X logic bug'
1831 0 : call mesa_error(__FILE__,__LINE__)
1832 : end if
1833 :
1834 : if (dbg_for_X) then
1835 : write(*, *) 'X', X
1836 : write(*, *) 'ix_lo', ix_lo
1837 : write(*, *) 'ix_hi', ix_hi
1838 : end if
1839 :
1840 421316 : what_we_use_is_equal_spaced = .true.
1841 421316 : dX1 = xz% Xs_for_Z(ix_lo+1,iz)-xz% Xs_for_Z(ix_lo,iz)
1842 421316 : dX2 = xz% Xs_for_Z(ix_lo+2,iz)-xz% Xs_for_Z(ix_lo+1,iz)
1843 421316 : if (ix_hi-ix_lo==2) then ! check that the 3 table X's are equal spaced
1844 76 : if (abs(dX1 - dX2) > tiny) what_we_use_is_equal_spaced = .false.
1845 : else ! check that the 4 table X's are equal spaced
1846 421240 : dX3 = xz% Xs_for_Z(ix_hi,iz)-xz% Xs_for_Z(ix_lo+2,iz)
1847 421240 : if (abs(dX1 - dX2) > tiny .or. abs(dX2 - dX3) > tiny) &
1848 : what_we_use_is_equal_spaced = .false.
1849 : end if
1850 :
1851 : if (.not. what_we_use_is_equal_spaced) then
1852 0 : call do_linear
1853 0 : if (is_bad(d_dX(1))) then
1854 0 : call mesa_error(__FILE__,__LINE__,'Get1_eosdt_for_X bad d_dX; linear')
1855 : end if
1856 0 : return
1857 : end if
1858 :
1859 2106504 : do ix=ix_lo, ix_hi
1860 1685188 : j = ix-ix_lo+1
1861 : call Get1_eosdt_XTable_Results( &
1862 : rq, which_eosdt, ix, iz, Rho, logRho, T, logT, &
1863 : res_zx(:, j), dlnd_zx(:, j), dlnT_zx(:, j), &
1864 1685188 : ierr)
1865 2106504 : if (ierr /= 0) return
1866 : end do
1867 :
1868 : ! zero these for now
1869 7162372 : res_zx(i_phase:i_latent_ddlnRho,:) = 0d0
1870 13903428 : res_zx(i_frac:i_frac+num_eos_frac_results-1,:) = 0d0
1871 :
1872 7162372 : dlnd_zx(i_phase:i_latent_ddlnRho,:) = 0d0
1873 13903428 : dlnd_zx(i_frac:i_frac+num_eos_frac_results-1,:) = 0d0
1874 :
1875 7162372 : dlnT_zx(i_phase:i_latent_ddlnRho,:) = 0d0
1876 13903428 : dlnT_zx(i_frac:i_frac+num_eos_frac_results-1,:) = 0d0
1877 :
1878 :
1879 421316 : delX = X - xz% Xs_for_Z(ix_lo,iz)
1880 421316 : dX = dX1
1881 :
1882 421316 : if (ix_hi-ix_lo==2) then
1883 :
1884 76 : denom = 2*dX*dX
1885 76 : c(1) = (2*dX*dX - 3*dX*delX + delX*delX)/denom
1886 76 : c(2) = 2*(2*dX-delX)*delX/denom
1887 76 : c(3) = delX*(delX-dX)/denom
1888 2052 : res(:) = c(1)*res_zx(:, 1) + c(2)*res_zx(:, 2) + c(3)*res_zx(:, 3)
1889 :
1890 : dlnd(:) = &
1891 : c(1)*dlnd_zx(:,1) + &
1892 : c(2)*dlnd_zx(:,2) + &
1893 2052 : c(3)*dlnd_zx(:,3)
1894 : dlnT(:) = &
1895 : c(1)*dlnT_zx(:,1) + &
1896 : c(2)*dlnT_zx(:,2) + &
1897 2052 : c(3)*dlnT_zx(:,3)
1898 :
1899 76 : dcdx(1) = (-3*dX + 2*delX)/denom
1900 76 : dcdx(2) = 2*(2*dX-2*delX)/denom
1901 76 : dcdx(3) = (2*delX-dX)/denom
1902 :
1903 : d_dX(:) = &
1904 : dcdX(1)*res_zx(:,1) + &
1905 : dcdX(2)*res_zx(:,2) + &
1906 2052 : dcdX(3)*res_zx(:,3)
1907 :
1908 76 : if (is_bad(d_dX(1))) then
1909 0 : call mesa_error(__FILE__,__LINE__,'Get1_eosdt_for_X bad d_dX; 3')
1910 : end if
1911 :
1912 : else
1913 :
1914 421240 : coef = (X-xz% Xs_for_Z(ix_lo+1,iz))/dX
1915 : ! coef = fractional location of X between 2nd and 3rd X's for fit.
1916 : ! coef is weight for the quadratic based on points 2, 3, 4 of fit.
1917 : ! (1-coef) is weight for quadratic based on points 1, 2, 3 of fit.
1918 421240 : coef = min(1d0,max(0d0,coef))
1919 421240 : c(1) = -coef*(coef-1)*(coef-1)/2
1920 421240 : c(2) = (2 - coef*coef*(5 - 3*coef))/2
1921 421240 : c(3) = coef*(1 + coef*(4 - 3*coef))/2
1922 421240 : c(4) = coef*coef*(coef-1)/2
1923 : res(:) = c(1)*res_zx(:, 1) + &
1924 : (c(2)*res_zx(:, 2) + &
1925 : (c(3)*res_zx(:, 3) + &
1926 11373480 : c(4)*res_zx(:, 4)))
1927 :
1928 : dlnd(:) = &
1929 : c(1)*dlnd_zx(:, 1) + &
1930 : (c(2)*dlnd_zx(:, 2) + &
1931 : (c(3)*dlnd_zx(:, 3) + &
1932 11373480 : c(4)*dlnd_zx(:, 4)))
1933 : dlnT(:) = &
1934 : c(1)*dlnT_zx(:, 1) + &
1935 : (c(2)*dlnT_zx(:, 2) + &
1936 : (c(3)*dlnT_zx(:, 3) + &
1937 11373480 : c(4)*dlnT_zx(:, 4)))
1938 :
1939 421240 : dcoef_dX = 1d0/dX
1940 : dcdX = 0
1941 421240 : dcdX(1) = -(3*coef*coef-4*coef+1)/2*dcoef_dX
1942 421240 : dcdX(2) = (9*coef*coef-10*coef)/2*dcoef_dX
1943 421240 : dcdX(3) = -(9*coef*coef-8*coef-1)/2*dcoef_dX
1944 421240 : dcdX(4) = coef*(3*coef-2)/2*dcoef_dX
1945 :
1946 : d_dX(:) = &
1947 : dcdX(1)*res_zx(:,1) + &
1948 : dcdX(2)*res_zx(:,2) + &
1949 : dcdX(3)*res_zx(:,3) + &
1950 11373480 : dcdX(4)*res_zx(:,4)
1951 :
1952 421240 : if (is_bad(d_dX(1))) then
1953 0 : call mesa_error(__FILE__,__LINE__,'Get1_eosdt_for_X bad d_dX; 4')
1954 : end if
1955 :
1956 : end if
1957 :
1958 : contains
1959 :
1960 0 : subroutine do_linear
1961 :
1962 0 : do ix = 2, num_Xs
1963 0 : if (xz% Xs_for_Z(ix,iz) >= X) exit
1964 : end do
1965 :
1966 0 : j = 1
1967 : call Get1_eosdt_XTable_Results( &
1968 : rq, which_eosdt, ix-1, iz, Rho, logRho, T, logT, &
1969 : res_zx(:,j), dlnd_zx(:,j), dlnT_zx(:,j), &
1970 0 : ierr)
1971 0 : if (ierr /= 0) then
1972 : if (.not. stop_for_is_bad) return
1973 : call mesa_error(__FILE__,__LINE__,'Get1_eosdt_for_X')
1974 : end if
1975 :
1976 0 : j = 2
1977 : call Get1_eosdt_XTable_Results( &
1978 : rq, which_eosdt, ix, iz, Rho, logRho, T, logT, &
1979 : res_zx(:,j), dlnd_zx(:,j), dlnT_zx(:,j), &
1980 0 : ierr)
1981 0 : if (ierr /= 0) then
1982 : if (.not. stop_for_is_bad) return
1983 : call mesa_error(__FILE__,__LINE__,'Get1_eosdt_for_X')
1984 : end if
1985 :
1986 : ! zero these for now
1987 0 : res_zx(i_phase:i_latent_ddlnRho,:) = 0d0
1988 0 : res_zx(i_frac:i_frac+num_eos_frac_results-1,:) = 0d0
1989 :
1990 0 : dlnd_zx(i_phase:i_latent_ddlnRho,:) = 0d0
1991 0 : dlnd_zx(i_frac:i_frac+num_eos_frac_results-1,:) = 0d0
1992 :
1993 0 : dlnT_zx(i_phase:i_latent_ddlnRho,:) = 0d0
1994 0 : dlnT_zx(i_frac:i_frac+num_eos_frac_results-1,:) = 0d0
1995 :
1996 :
1997 0 : alfa = (X - xz% Xs_for_Z(ix,iz))/(xz% Xs_for_Z(ix-1,iz) - xz% Xs_for_Z(ix,iz))
1998 0 : beta = 1d0 - alfa
1999 :
2000 0 : dalfa_dX = 1d0 / (xz% Xs_for_Z(ix-1,iz) - xz% Xs_for_Z(ix,iz))
2001 0 : dbeta_dX = -dalfa_dX
2002 :
2003 0 : do j=1,nv
2004 :
2005 0 : res(j) = alfa*res_zx(j,1) + beta*res_zx(j,2)
2006 :
2007 : dlnd(j) = &
2008 0 : alfa*dlnd_zx(j,1) + beta*dlnd_zx(j,2)
2009 :
2010 : dlnT(j) = &
2011 0 : alfa*dlnT_zx(j,1) + beta*dlnT_zx(j,2)
2012 :
2013 : d_dX(j) = &
2014 0 : dalfa_dX*res_zx(j,1) + dbeta_dX*res_zx(j,2)
2015 :
2016 : end do
2017 :
2018 : end subroutine do_linear
2019 :
2020 : end subroutine Get1_eosdt_for_X
2021 :
2022 :
2023 1685204 : subroutine Locate_logQ(rq, ep, logQ, iQ, logQ0, logQ1, ierr)
2024 : type (EoS_General_Info), pointer :: rq
2025 : type (EosDT_xz_Info), pointer :: ep
2026 : real(dp), intent(inout) :: logQ
2027 : integer, intent(out) :: iQ
2028 : real(dp), intent(out) :: logQ0, logQ1
2029 : integer, intent(out) :: ierr
2030 1685204 : ierr = 0
2031 1685204 : iQ = int((logQ - ep% logQ_min)/ep% del_logQ + 1d-4) + 1
2032 1685204 : if (iQ < 1 .or. iQ >= ep% num_logQs) then
2033 0 : if (iQ < 1) then
2034 0 : iQ = 1
2035 0 : logQ0 = ep% logQ_min
2036 0 : logQ1 = logQ0 + ep% del_logQ
2037 0 : logQ = logQ0
2038 0 : if (return_ierr_beyond_table_bounds) ierr = -1
2039 : else
2040 0 : iQ = ep% num_logQs-1
2041 0 : logQ0 = ep% logQ_min + (iQ-1)*ep% del_logQ
2042 0 : logQ1 = logQ0 + ep% del_logQ
2043 0 : logQ = logQ1
2044 0 : if (return_ierr_beyond_table_bounds) ierr = -1
2045 : end if
2046 : else
2047 1685204 : logQ0 = ep% logQ_min + (iQ-1)*ep% del_logQ
2048 1685204 : logQ1 = logQ0 + ep% del_logQ
2049 : end if
2050 1685204 : end subroutine Locate_logQ
2051 :
2052 :
2053 1685204 : subroutine Locate_logT(rq, ep, logT, iT, logT0, logT1, ierr)
2054 : type (EoS_General_Info), pointer :: rq
2055 : type (EosDT_xz_Info), pointer :: ep
2056 : real(dp), intent(inout) :: logT
2057 : integer, intent(out) :: iT
2058 : real(dp), intent(out) :: logT0, logT1
2059 : integer, intent(out) :: ierr
2060 1685204 : ierr = 0
2061 1685204 : iT = int((logT - ep% logT_min)/ep% del_logT + 1d-4) + 1
2062 1685204 : if (iT < 1 .or. iT >= ep% num_logTs) then
2063 0 : if (iT < 1) then
2064 0 : iT = 1
2065 0 : logT0 = ep% logT_min
2066 0 : logT1 = logT0 + ep% del_logT
2067 0 : logT = logT0
2068 0 : if (return_ierr_beyond_table_bounds) ierr = -1
2069 : else
2070 0 : iT = ep% num_logTs-1
2071 0 : logT0 = ep% logT_min + (iT-1)*ep% del_logT
2072 0 : logT1 = logT0 + ep% del_logT
2073 0 : logT = logT1
2074 0 : if (return_ierr_beyond_table_bounds) ierr = -1
2075 : end if
2076 : else
2077 1685204 : logT0 = ep% logT_min + (iT-1)*ep% del_logT
2078 1685204 : logT1 = logT0 + ep% del_logT
2079 : end if
2080 1685204 : end subroutine Locate_logT
2081 :
2082 :
2083 1685204 : subroutine Get1_eosdt_XTable_Results( &
2084 : rq, which_eosdt, ix, iz, Rho, logRho_in, T, logT_in, &
2085 : res, d_dlnd, d_dlnT, ierr)
2086 : use eosdt_support, only: Do_EoS_Interpolations
2087 : type (EoS_General_Info), pointer :: rq
2088 : integer, intent(in) :: which_eosdt
2089 : integer, intent(in) :: ix, iz
2090 : real(dp), intent(in) :: Rho, logRho_in, T, logT_in
2091 : real(dp), intent(inout), dimension(nv) :: res, d_dlnd, d_dlnT
2092 : integer, intent(out) :: ierr
2093 :
2094 : real(dp), parameter :: ln10sq = ln10*ln10
2095 : real(dp) :: &
2096 133131116 : fval(nv), df_dx(nv), df_dy(nv), &
2097 89315812 : df_dlnd(nv), df_dlnT(nv), &
2098 : energy, entropy, P, Pgas, Prad, x, y, &
2099 : dx_dlnd, dx_dlnT, dy_dlnd, dy_dlnT, &
2100 : chiT, chiRho, Cv, gamma1, numeric, &
2101 : dS_dlnd, dS_dlnT, dE_dlnd, dE_dlnT, &
2102 : dPgas_dlnd, dPgas_dlnT, dP_dlnd, dP_dlnT
2103 1685204 : real(dp) :: logQ0, logQ1, logT0, logT1, logRho0, logRho1
2104 : integer :: iQ, jtemp, k, j, irho
2105 : type (EosDT_xz_Info), pointer :: ep
2106 : logical, parameter :: show = .false.
2107 1685204 : real(dp) :: logRho, logT, logQ
2108 :
2109 : include 'formats'
2110 :
2111 1685204 : logRho = logRho_in
2112 1685204 : logT = logT_in
2113 1685204 : logQ = logRho - 2*logT + 12
2114 :
2115 : ierr = 0
2116 1685204 : call load_single_eosDT_table_by_id(rq, which_eosdt, ep, ix, iz, ierr)
2117 1685204 : if (ierr /= 0) return
2118 :
2119 1685204 : call Locate_logQ(rq, ep, logQ, iQ, logQ0, logQ1, ierr)
2120 1685204 : if (ierr /= 0) then
2121 0 : write(*,1) 'eosDT failed in Locate_logQ', logQ
2122 0 : return
2123 : end if
2124 :
2125 1685204 : call Locate_logT(rq, ep, logT, jtemp, logT0, logT1, ierr)
2126 1685204 : if (ierr /= 0) then
2127 0 : write(*,1) 'eosDT failed in Locate_logT', logT
2128 0 : return
2129 : end if
2130 :
2131 : call Do_EoS_Interpolations( &
2132 : 1, nv, nv, ep% num_logQs, ep% logQs, ep% num_logTs, ep% logTs, &
2133 : ep% tbl1, iQ, jtemp, logQ0, logQ, logQ1, logT0, logT, logT1, &
2134 1685204 : fval, df_dx, df_dy, ierr)
2135 1685204 : if (ierr /= 0) then
2136 0 : write(*,1) 'failed in Do_EoS_Interpolations'
2137 0 : return
2138 : end if
2139 :
2140 1685204 : if (is_bad(fval(i_lnS))) then
2141 0 : ierr = -1
2142 0 : if (.not. stop_for_is_bad) return
2143 : write(*,1) 'fval(i_lnS), logRho, logT', fval(i_lnS), logRho, logT
2144 : call mesa_error(__FILE__,__LINE__,'after Do_Interp_with_2nd_derivs')
2145 : end if
2146 :
2147 1685204 : res(i_lnPgas) = fval(i_lnPgas)
2148 1685204 : res(i_lnE) = fval(i_lnE)
2149 1685204 : res(i_lnS) = fval(i_lnS)
2150 :
2151 1685204 : if (is_bad(res(i_lnS))) then
2152 0 : ierr = -1
2153 0 : if (.not. stop_for_is_bad) return
2154 : write(*,1) 'res(i_lnS), logRho, logT', res(i_lnS), logRho, logT
2155 : call mesa_error(__FILE__,__LINE__,'after interpolation')
2156 : end if
2157 :
2158 1685204 : if (is_bad(res(i_lnS)) .or. res(i_lnS) > ln10*100) then
2159 0 : ierr = -1
2160 0 : if (.not. stop_for_is_bad) return
2161 : write(*,1) 'res(i_lnS), logRho, logT', res(i_lnS), logRho, logT
2162 : call mesa_error(__FILE__,__LINE__,'after interpolation')
2163 : end if
2164 :
2165 1685204 : res(i_grad_ad) = fval(i_grad_ad)
2166 1685204 : res(i_chiRho) = fval(i_chiRho)
2167 1685204 : res(i_chiT) = fval(i_chiT)
2168 :
2169 1685204 : res(i_Cp) = fval(i_Cp)
2170 1685204 : res(i_Cv) = fval(i_Cv)
2171 :
2172 1685204 : res(i_dE_dRho) = fval(i_dE_dRho)
2173 1685204 : res(i_dS_dT) = fval(i_dS_dT)
2174 1685204 : res(i_dS_dRho) = fval(i_dS_dRho)
2175 :
2176 1685204 : res(i_mu) = fval(i_mu)
2177 1685204 : res(i_lnfree_e) = fval(i_lnfree_e)
2178 1685204 : res(i_gamma1) = fval(i_gamma1)
2179 1685204 : res(i_gamma3) = fval(i_gamma3)
2180 1685204 : res(i_eta) = fval(i_eta)
2181 :
2182 : ! convert df_dx and df_dy to df_dlogRho_c_T and df_dlogT_c_Rho
2183 :
2184 : ! df_dx is df_dlogQ at const T
2185 : ! df_dy is df_dlogT_c_Rho at const Q
2186 : ! logQ = logRho - 2*logT + 12
2187 :
2188 : ! f = f(logQ(logRho,logT),logT)
2189 : ! df/dlogRho|T = df/dlogQ|T * dlogQ/dlogRho|T = df_dx
2190 : ! df/dlogT|Rho = df/dlogT|Q + df/dlogQ|T * dlogQ/dlogT|Rho = df_dy - 2*df_dx
2191 :
2192 45500508 : do k=1,nv
2193 43815304 : df_dlnd(k) = df_dx(k)/ln10
2194 45500508 : df_dlnT(k) = df_dy(k)/ln10 - 2d0*df_dlnd(k)
2195 : end do
2196 :
2197 1685204 : d_dlnd(i_lnPgas) = df_dlnd(i_lnPgas)
2198 1685204 : d_dlnd(i_lnE) = df_dlnd(i_lnE)
2199 1685204 : d_dlnd(i_lnS) = df_dlnd(i_lnS)
2200 1685204 : d_dlnd(i_grad_ad) = df_dlnd(i_grad_ad)
2201 1685204 : d_dlnd(i_chiRho) = df_dlnd(i_chiRho)
2202 1685204 : d_dlnd(i_chiT) = df_dlnd(i_chiT)
2203 :
2204 1685204 : d_dlnd(i_Cp) = df_dlnd(i_Cp)
2205 1685204 : d_dlnd(i_Cv) = df_dlnd(i_Cv)
2206 1685204 : d_dlnd(i_dE_dRho) = df_dlnd(i_dE_dRho)
2207 1685204 : d_dlnd(i_dS_dT) = df_dlnd(i_dS_dT)
2208 1685204 : d_dlnd(i_dS_dRho) = df_dlnd(i_dS_dRho)
2209 1685204 : d_dlnd(i_mu) = df_dlnd(i_mu)
2210 1685204 : d_dlnd(i_lnfree_e) = df_dlnd(i_lnfree_e)
2211 1685204 : d_dlnd(i_gamma1) = df_dlnd(i_gamma1)
2212 1685204 : d_dlnd(i_gamma3) = df_dlnd(i_gamma3)
2213 1685204 : d_dlnd(i_eta) = df_dlnd(i_eta)
2214 :
2215 1685204 : d_dlnT(i_lnPgas) = df_dlnT(i_lnPgas)
2216 1685204 : d_dlnT(i_lnE) = df_dlnT(i_lnE)
2217 1685204 : d_dlnT(i_lnS) = df_dlnT(i_lnS)
2218 1685204 : d_dlnT(i_grad_ad) = df_dlnT(i_grad_ad)
2219 1685204 : d_dlnT(i_chiRho) = df_dlnT(i_chiRho)
2220 1685204 : d_dlnT(i_chiT) = df_dlnT(i_chiT)
2221 1685204 : d_dlnT(i_Cp) = df_dlnT(i_Cp)
2222 1685204 : d_dlnT(i_Cv) = df_dlnT(i_Cv)
2223 1685204 : d_dlnT(i_dE_dRho) = df_dlnT(i_dE_dRho)
2224 1685204 : d_dlnT(i_dS_dT) = df_dlnT(i_dS_dT)
2225 1685204 : d_dlnT(i_dS_dRho) = df_dlnT(i_dS_dRho)
2226 1685204 : d_dlnT(i_mu) = df_dlnT(i_mu)
2227 1685204 : d_dlnT(i_lnfree_e) = df_dlnT(i_lnfree_e)
2228 1685204 : d_dlnT(i_gamma1) = df_dlnT(i_gamma1)
2229 1685204 : d_dlnT(i_gamma3) = df_dlnT(i_gamma3)
2230 1685204 : d_dlnT(i_eta) = df_dlnT(i_eta)
2231 :
2232 1685204 : if (is_bad(d_dlnd(i_lnS)) .or. is_bad(d_dlnT(i_lnS))) then
2233 0 : ierr = -1
2234 0 : if (.not. stop_for_is_bad) return
2235 : write(*,1) 'fval(i_lnS)', fval(i_lnS)
2236 : write(*,1) 'd_dlnd(i_lnS)', d_dlnd(i_lnS)
2237 : write(*,1) 'd_dlnT(i_lnS)', d_dlnT(i_lnS)
2238 : call mesa_error(__FILE__,__LINE__,'Get1_eosdt_XTable_Results')
2239 : end if
2240 :
2241 1685204 : end subroutine Get1_eosdt_XTable_Results
2242 :
2243 :
2244 1476 : subroutine get_T( &
2245 : handle, Z, X, abar, zbar, &
2246 1476 : species, chem_id, net_iso, xa, &
2247 : logRho, which_other, other_value, &
2248 : logT_tol, other_tol, max_iter, logT_guess, &
2249 : logT_bnd1, logT_bnd2, other_at_bnd1, other_at_bnd2, &
2250 1476 : logT_result, res, d_dlnRho_c_T, d_dlnT_c_Rho, d_dxa_c_TRho, &
2251 : eos_calls, ierr)
2252 :
2253 : integer, intent(in) :: handle
2254 :
2255 : real(dp), intent(in) :: Z ! the metals mass fraction
2256 : real(dp), intent(in) :: X ! the hydrogen mass fraction
2257 :
2258 : real(dp), intent(in) :: abar, zbar
2259 :
2260 : integer, intent(in) :: species
2261 : integer, pointer :: chem_id(:)
2262 : integer, pointer :: net_iso(:)
2263 : real(dp), intent(in) :: xa(:)
2264 :
2265 : real(dp), intent(in) :: logRho ! log10 of density
2266 : integer, intent(in) :: which_other ! from eos_def. e.g., i_P for pressure
2267 : real(dp), intent(in) :: other_value ! desired value for the other variable
2268 : real(dp), intent(in) :: other_tol
2269 :
2270 : real(dp), intent(in) :: logT_tol
2271 : integer, intent(in) :: max_iter ! max number of iterations
2272 :
2273 : real(dp), intent(in) :: logT_guess
2274 : real(dp), intent(in) :: logT_bnd1, logT_bnd2 ! bounds for logT
2275 : ! set to arg_not_provided if do not know bounds
2276 : real(dp), intent(in) :: other_at_bnd1, other_at_bnd2 ! values at bounds
2277 : ! if don't know these values, just set to arg_not_provided (defined in c_def)
2278 :
2279 : real(dp), intent(out) :: logT_result
2280 : real(dp), intent(inout), dimension(nv) :: res, d_dlnRho_c_T, d_dlnT_c_Rho
2281 : real(dp), intent(inout), dimension(:,:) :: d_dxa_c_TRho
2282 :
2283 : integer, intent(out) :: eos_calls
2284 : integer, intent(out) :: ierr ! 0 means AOK.
2285 :
2286 : logical, parameter :: doing_Rho = .false.
2287 :
2288 : call do_safe_get_Rho_T( &
2289 : handle, Z, X, abar, zbar, &
2290 : species, chem_id, net_iso, xa, &
2291 : logRho, which_other, other_value, doing_Rho, &
2292 : logT_guess, logT_result, logT_bnd1, logT_bnd2, other_at_bnd1, other_at_bnd2, &
2293 : logT_tol, other_tol, max_iter, res, d_dlnRho_c_T, d_dlnT_c_Rho, d_dxa_c_TRho, &
2294 1476 : eos_calls, ierr)
2295 :
2296 1685204 : end subroutine get_T
2297 :
2298 :
2299 12152 : subroutine get_Rho( &
2300 : handle, Z, X, abar, zbar, &
2301 12152 : species, chem_id, net_iso, xa, &
2302 : logT, which_other, other_value, &
2303 : logRho_tol, other_tol, max_iter, logRho_guess, &
2304 : logRho_bnd1, logRho_bnd2, other_at_bnd1, other_at_bnd2, &
2305 12152 : logRho_result, res, d_dlnRho_c_T, d_dlnT_c_Rho, d_dxa_c_TRho, &
2306 : eos_calls, ierr)
2307 :
2308 : use const_def, only: dp
2309 :
2310 : integer, intent(in) :: handle
2311 :
2312 : real(dp), intent(in) :: Z ! the metals mass fraction
2313 : real(dp), intent(in) :: X ! the hydrogen mass fraction
2314 :
2315 : real(dp), intent(in) :: abar, zbar
2316 :
2317 : integer, intent(in) :: species
2318 : integer, pointer :: chem_id(:)
2319 : integer, pointer :: net_iso(:)
2320 : real(dp), intent(in) :: xa(:)
2321 :
2322 : real(dp), intent(in) :: logT ! log10 of temperature
2323 :
2324 : integer, intent(in) :: which_other ! from eos_def.
2325 : real(dp), intent(in) :: other_value ! desired value for the other variable
2326 : real(dp), intent(in) :: other_tol
2327 :
2328 : real(dp), intent(in) :: logRho_tol
2329 :
2330 : integer, intent(in) :: max_iter ! max number of Newton iterations
2331 :
2332 : real(dp), intent(in) :: logRho_guess
2333 : real(dp), intent(in) :: logRho_bnd1, logRho_bnd2 ! bounds for logrho
2334 : ! set to arg_not_provided if do not know bounds
2335 : real(dp), intent(in) :: other_at_bnd1, other_at_bnd2 ! values at bounds
2336 : ! if don't know these values, just set to arg_not_provided (defined in c_def)
2337 :
2338 : real(dp), intent(out) :: logRho_result
2339 : real(dp), intent(inout), dimension(nv) :: res, d_dlnRho_c_T, d_dlnT_c_Rho
2340 : real(dp), intent(inout), dimension(:,:) :: d_dxa_c_TRho
2341 :
2342 : integer, intent(out) :: eos_calls
2343 : integer, intent(out) :: ierr ! 0 means AOK.
2344 :
2345 : logical, parameter :: doing_Rho = .true.
2346 : real(dp) :: Prad
2347 :
2348 : call do_safe_get_Rho_T( &
2349 : handle, Z, X, abar, zbar, &
2350 : species, chem_id, net_iso, xa, &
2351 : logT, which_other, other_value, doing_Rho, &
2352 : logRho_guess, logRho_result, logRho_bnd1, logRho_bnd2, other_at_bnd1, other_at_bnd2, &
2353 : logRho_tol, other_tol, max_iter, res, d_dlnRho_c_T, d_dlnT_c_Rho, d_dxa_c_TRho, &
2354 12152 : eos_calls, ierr)
2355 :
2356 12152 : end subroutine get_Rho
2357 :
2358 :
2359 13628 : subroutine do_safe_get_Rho_T( &
2360 : handle, Z, XH1, abar, zbar, &
2361 13628 : species, chem_id, net_iso, xa, &
2362 : the_other_log, which_other, other_value, doing_Rho, &
2363 : initial_guess, x, xbnd1, xbnd2, other_at_bnd1, other_at_bnd2, &
2364 : xacc, yacc, ntry, &
2365 13628 : res, d_dlnRho_c_T, d_dlnT_c_Rho, d_dxa_c_TRho, &
2366 : eos_calls, ierr)
2367 : use const_def, only: dp
2368 : use chem_def, only: num_chem_isos
2369 : use num_lib, only: safe_root_with_guess
2370 : integer, intent(in) :: handle
2371 : real(dp), intent(in) :: Z, XH1, abar, zbar
2372 : integer, intent(in) :: species
2373 : integer, pointer :: chem_id(:)
2374 : integer, pointer :: net_iso(:)
2375 : real(dp), intent(in) :: xa(:)
2376 : integer, intent(in) :: which_other ! 0 means total P
2377 : real(dp), intent(in) :: other_value
2378 : logical, intent(in) :: doing_Rho
2379 : real(dp), intent(in) :: initial_guess ! for x
2380 : real(dp), intent(out) :: x ! if doing_Rho, then logRho, else logT
2381 : real(dp), intent(in) :: the_other_log
2382 : real(dp), intent(in) :: xbnd1, xbnd2, other_at_bnd1, other_at_bnd2
2383 : real(dp), intent(in) :: xacc, yacc ! tolerances
2384 : integer, intent(in) :: ntry ! max number of iterations
2385 : real(dp), intent(inout), dimension(nv) :: res, d_dlnRho_c_T, d_dlnT_c_Rho
2386 : real(dp), dimension(:,:) :: d_dxa_c_TRho
2387 : integer, intent(out) :: eos_calls, ierr
2388 :
2389 : integer :: i, j, ix, iz
2390 : integer, parameter :: lrpar = 0, lipar = 0, newt_imax = 6
2391 : real(dp), parameter :: dx = 0.1d0
2392 13628 : integer, pointer :: ipar(:)
2393 13628 : real(dp), pointer :: rpar(:)
2394 13628 : real(dp) :: the_other_val, logRho, logT, rho, T, x1, x3, y1, y3
2395 : type (EoS_General_Info), pointer :: rq
2396 :
2397 : include 'formats'
2398 :
2399 : ierr = 0
2400 :
2401 13628 : call get_eos_ptr(handle, rq, ierr)
2402 13628 : if (ierr /= 0) then
2403 0 : write(*, *) 'get_eos_ptr returned ierr', ierr
2404 : return
2405 : end if
2406 :
2407 13628 : x1 = arg_not_provided
2408 13628 : x3 = arg_not_provided
2409 13628 : y1 = arg_not_provided
2410 13628 : y3 = arg_not_provided
2411 :
2412 13628 : eos_calls = 0
2413 13628 : the_other_val = exp10(the_other_log)
2414 13628 : nullify(ipar, rpar)
2415 :
2416 : x = safe_root_with_guess( &
2417 : f, initial_guess, dx, x1, x3, y1, y3, &
2418 : min(ntry,newt_imax), ntry, xacc, yacc, &
2419 27256 : lrpar, rpar, lipar, ipar, ierr)
2420 :
2421 : contains
2422 :
2423 45564 : real(dp) function f(x, dfdx, lrpar, rpar, lipar, ipar, ierr)
2424 : ! returns with ierr = 0 if was able to evaluate f and df/dx at x
2425 : ! if df/dx not available, it is okay to set it to 0
2426 13628 : use const_def, only: dp
2427 : integer, intent(in) :: lrpar, lipar
2428 : real(dp), intent(in) :: x
2429 : real(dp), intent(out) :: dfdx
2430 : integer, intent(inout), pointer :: ipar(:) ! (lipar)
2431 : real(dp), intent(inout), pointer :: rpar(:) ! (lrpar)
2432 : integer, intent(out) :: ierr
2433 :
2434 45564 : real(dp) :: Pgas, Prad, energy, entropy, dPgas_dlnT, dPrad_dlnT, &
2435 45564 : dPgas_dlnRho, erad, egas, derad_dlnT, degas_dlnT, derad_dlnRho
2436 :
2437 : include 'formats'
2438 45564 : ierr = 0
2439 45564 : eos_calls = eos_calls + 1
2440 45564 : f = 0; dfdx = 0
2441 :
2442 45564 : if (x > 50d0) then
2443 0 : ierr = -1
2444 0 : return
2445 : end if
2446 :
2447 45564 : if (doing_Rho) then
2448 42460 : logRho = x
2449 42460 : rho = exp10(logRho)
2450 42460 : logT = the_other_log
2451 42460 : T = the_other_val
2452 : else
2453 3104 : logT = x
2454 3104 : T = exp10(logT)
2455 3104 : logRho = the_other_log
2456 3104 : rho = the_other_val
2457 : end if
2458 :
2459 : call Get_eosDT_Results(rq, Z, XH1, abar, zbar, &
2460 : species, chem_id, net_iso, xa, &
2461 : rho, logRho, T, logT, &
2462 45564 : res, d_dlnRho_c_T, d_dlnT_c_Rho, d_dxa_c_TRho, ierr)
2463 :
2464 45564 : Pgas = exp(res(i_lnPgas))
2465 45564 : Prad = crad*T*T*T*T/3d0
2466 45564 : energy = exp(res(i_lnE))
2467 45564 : entropy = exp(res(i_lnS))
2468 :
2469 45564 : if (ierr /= 0) then
2470 : if (.false.) then
2471 : write(*,*) 'Get_eosDT_Results returned ierr', ierr
2472 : write(*,1) 'Z', Z
2473 : write(*,1) 'XH1', XH1
2474 : write(*,1) 'abar', abar
2475 : write(*,1) 'zbar', zbar
2476 : write(*,1) 'rho', rho
2477 : write(*,1) 'logRho', logRho
2478 : write(*,1) 'T', T
2479 : write(*,1) 'logT', logT
2480 : write(*,'(A)')
2481 : call mesa_error(__FILE__,__LINE__,'do_safe_get_Rho_T')
2482 : end if
2483 : return
2484 : end if
2485 :
2486 45564 : if (is_bad(res(i_Cv))) then
2487 0 : ierr = -1
2488 0 : if (.not. stop_for_is_bad) return
2489 : write(*,1) 'res(i_Cv)', res(i_Cv)
2490 : write(*,1) 'Z', Z
2491 : write(*,1) 'XH1', XH1
2492 : write(*,1) 'abar', abar
2493 : write(*,1) 'zbar', zbar
2494 : write(*,1) 'rho', rho
2495 : write(*,1) 'logRho', logRho
2496 : write(*,1) 'T', T
2497 : write(*,1) 'logT', logT
2498 : write(*,'(A)')
2499 : call mesa_error(__FILE__,__LINE__,'do_safe_get_Rho_T')
2500 : end if
2501 :
2502 45564 : if (which_other == -1) then ! other_value is egas
2503 0 : erad = crad*pow4(T)/rho
2504 0 : egas = energy - erad
2505 0 : f = egas - other_value
2506 0 : if (doing_Rho) then
2507 0 : derad_dlnRho = -erad
2508 0 : dfdx = energy*d_dlnRho_c_T(i_lnE)*ln10 - derad_dlnRho
2509 : else
2510 0 : derad_dlnT = 4d0*erad
2511 0 : degas_dlnT = energy*d_dlnT_c_Rho(i_lnE) - derad_dlnT
2512 0 : dfdx = degas_dlnT*ln10
2513 : end if
2514 45564 : else if (which_other == 0) then ! other_value is log10P
2515 36 : f = log10(Pgas + Prad) - other_value
2516 36 : if (doing_Rho) then
2517 0 : dPgas_dlnRho = Pgas*d_dlnRho_c_T(i_lnPgas)
2518 0 : dfdx = dPgas_dlnRho/(Pgas + Prad)*ln10
2519 : else
2520 36 : dPgas_dlnT = Pgas*d_dlnT_c_Rho(i_lnPgas)
2521 36 : dPrad_dlnT = 4d0*Prad
2522 36 : dfdx = (dPgas_dlnT + dPrad_dlnT)/(Pgas + Prad)*ln10
2523 : end if
2524 : else
2525 45528 : f = res(which_other) - other_value
2526 45528 : if (doing_Rho) then
2527 42460 : dfdx = d_dlnRho_c_T(which_other)*ln10
2528 : else
2529 3068 : dfdx = d_dlnT_c_Rho(which_other)*ln10
2530 : end if
2531 : end if
2532 :
2533 : end function f
2534 :
2535 : end subroutine do_safe_get_Rho_T
2536 :
2537 : end module eosDT_eval
|