MPI-AMRVAC 3.2
The MPI - Adaptive Mesh Refinement - Versatile Advection Code (development version)
Loading...
Searching...
No Matches
mod_eos_LTE_entropy.t
Go to the documentation of this file.
1!=============================================================================
2!> Entropy-method LTE EoS: every query is ONE bicubic Hermite evaluation.
3!>
4!> Each quantity is stored as four tables -- the value plus its three
5!> derivatives (d/dx, d/dy, d2/dxdy) at every node -- which fully determine
6!> the bicubic Hermite polynomial in each cell: exact at nodes, O(h^4) inside,
7!> no closure. No Newton, bisection, or iteration on the hot path; the
8!> iterative work is done offline against the analytic Saha solver (see
9!> entropy/generate_all_tables.py).
10!>
11!> Forward tables, axes (log10 nH, log10 eint/nH):
12!> Tfwd -> T pfwd -> p neOnH -> ne/nH
13!> Inverse tables:
14!> eintP (log nH, log p/nH) -> log10(eint/nH)
15!> eintT (log nH, log T) -> log10(eint/nH)
16!> g1p (log nH, log p/nH) -> Gamma_1
17!>
18!> Gamma_1 is tabulated directly (g1p) rather than recovered from second
19!> derivatives, so the lookup stays smooth; values are Maxwell-consistent with
20!> (p, T) by construction.
21!=============================================================================
24 use mod_comm_lib, only: mpistop
30 implicit none
31 private
32
33 double precision, parameter :: LN10 = 2.302585092994046d0
34
36
37 !> Forward (log nH, log eint/nH) -> thermodynamic state
42 !> Inverse (log nH, log p/nH) -> eint/p ratio, Gamma_1
45 !> Inverse (log nH, log T) -> log10(eint/nH)
47
48contains
49
50 !> Entropy-method load: six quantities, each a value table plus its three
51 !> derivative tables, on the forward (nH, eint/nH), inverse-p (nH, p/nH) and
52 !> inverse-T (nH, T) grids. Every runtime query is one bicubic-Hermite
53 !> evaluation (see generate_all_tables.py).
54 subroutine load_entropy_lte()
55 integer :: iq, id
56 character(len=8), parameter :: quantity(6) = &
57 [character(8):: 'neOnH', 'Tfwd', 'pfwd', 'eintP', 'g1p', 'eintT']
58 character(len=3), parameter :: deriv(4) = &
59 [character(3):: '', '_x', '_y', '_xy']
60
61 if (mype == 0) write(*,*) &
62 'EoS method: entropy (bicubic Hermite, 4-derivative corners, no closure)'
63 do iq = 1, size(quantity)
64 do id = 1, size(deriv)
65 call load_tables_lte(trim(quantity(iq))//trim(deriv(id)))
66 end do
67 end do
68 end subroutine load_entropy_lte
69
70 !> Entropy-method finalise: shift each loaded table's axes from CGS to code
71 !> units and run the standard prepare. No aux builds -- every runtime quantity
72 !> is a single Hermite lookup. neOnH/Tfwd/pfwd/eintP/g1p are on (log nH,
73 !> log eint/nH) (axis2_is_T=.false.); eintT is on (log nH, log T)
74 !> (axis2_is_T=.true.). Each quantity ships value + three derivative tables.
76 call entropy_shift_prepare(eos%neOnH, .false.)
77 call entropy_shift_prepare(eos%neOnH_x, .false.)
78 call entropy_shift_prepare(eos%neOnH_y, .false.)
79 call entropy_shift_prepare(eos%neOnH_xy, .false.)
80 call entropy_shift_prepare(eos%Tfwd, .false.)
81 call entropy_shift_prepare(eos%Tfwd_x, .false.)
82 call entropy_shift_prepare(eos%Tfwd_y, .false.)
83 call entropy_shift_prepare(eos%Tfwd_xy, .false.)
84 call entropy_shift_prepare(eos%pfwd, .false.)
85 call entropy_shift_prepare(eos%pfwd_x, .false.)
86 call entropy_shift_prepare(eos%pfwd_y, .false.)
87 call entropy_shift_prepare(eos%pfwd_xy, .false.)
88 call entropy_shift_prepare(eos%eintP, .false.)
89 call entropy_shift_prepare(eos%eintP_x, .false.)
90 call entropy_shift_prepare(eos%eintP_y, .false.)
91 call entropy_shift_prepare(eos%eintP_xy, .false.)
92 call entropy_shift_prepare(eos%g1p, .false.)
93 call entropy_shift_prepare(eos%g1p_x, .false.)
94 call entropy_shift_prepare(eos%g1p_y, .false.)
95 call entropy_shift_prepare(eos%g1p_xy, .false.)
96 call entropy_shift_prepare(eos%eintT, .true.)
97 call entropy_shift_prepare(eos%eintT_x, .true.)
98 call entropy_shift_prepare(eos%eintT_y, .true.)
99 call entropy_shift_prepare(eos%eintT_xy, .true.)
101 !> The entropy method never loads eos%T, but several callers read
102 !> eos%T%var{1,2}_{min,max} (the cold-cell eint floor, FI-fallback
103 !> checks). Source them from eos%Tfwd, on the same forward grid.
104 eos%T%var2_min = eos%Tfwd%var2_min
105 eos%T%var2_max = eos%Tfwd%var2_max
106 eos%T%var1_min = eos%Tfwd%var1_min
107 eos%T%var1_max = eos%Tfwd%var1_max
108 if (mype == 0) write(*,'(A)') &
109 ' EoS entropy: forward + inverse tables loaded; no aux builds.'
110 end subroutine finalise_entropy_lte
111
112 !> Index location: uniform and non-uniform variants.
113 pure subroutine locate_idx_uniform(n, vmin, vmax, val, ix, t, h)
114 integer, intent(in) :: n
115 double precision, intent(in) :: vmin, vmax, val
116 integer, intent(out) :: ix
117 double precision, intent(out) :: t, h
118 h = (vmax - vmin) / dble(n - 1)
119 if (val <= vmin) then
120 ix = 1; t = 0.0d0; return
121 end if
122 if (val >= vmax) then
123 ix = n - 1; t = 1.0d0; return
124 end if
125 ix = 1 + int((val - vmin) / h)
126 if (ix < 1) ix = 1
127 if (ix > n - 1) ix = n - 1
128 t = (val - (vmin + (ix - 1) * h)) / h
129 if (t < 0.0d0) t = 0.0d0
130 if (t > 1.0d0) t = 1.0d0
131 end subroutine locate_idx_uniform
132
133 pure subroutine locate_idx_nodes(n, nodes, val, ix, t, h)
134 integer, intent(in) :: n
135 double precision, intent(in) :: nodes(n), val
136 integer, intent(out) :: ix
137 double precision, intent(out) :: t, h
138 integer :: lo, mid, hi
139 if (val <= nodes(1)) then
140 ix = 1; t = 0.0d0; h = nodes(2) - nodes(1); return
141 end if
142 if (val >= nodes(n)) then
143 ix = n - 1; t = 1.0d0; h = nodes(n) - nodes(n - 1); return
144 end if
145 ! Binary search for cell containing val.
146 lo = 1; hi = n
147 do
148 if (hi - lo <= 1) exit
149 mid = (lo + hi) / 2
150 if (nodes(mid) <= val) then
151 lo = mid
152 else
153 hi = mid
154 end if
155 end do
156 ix = lo
157 h = nodes(ix + 1) - nodes(ix)
158 t = (val - nodes(ix)) / h
159 if (t < 0.0d0) t = 0.0d0
160 if (t > 1.0d0) t = 1.0d0
161 end subroutine locate_idx_nodes
162
163 pure subroutine locate_idx_axis1(tab, val, ix, t, h)
164 type(eos_table_container), intent(in) :: tab
165 double precision, intent(in) :: val
166 integer, intent(out) :: ix
167 double precision, intent(out) :: t, h
168 if (tab%is_uniform) then
169 call locate_idx_uniform(tab%dim1, tab%var1_min, tab%var1_max, val, ix, t, h)
170 else
171 call locate_idx_nodes(tab%dim1, tab%var1_nodes, val, ix, t, h)
172 end if
173 end subroutine locate_idx_axis1
174
175 pure subroutine locate_idx_axis2(tab, val, ix, t, h)
176 type(eos_table_container), intent(in) :: tab
177 double precision, intent(in) :: val
178 integer, intent(out) :: ix
179 double precision, intent(out) :: t, h
180 if (tab%is_uniform) then
181 call locate_idx_uniform(tab%dim2, tab%var2_min, tab%var2_max, val, ix, t, h)
182 else
183 call locate_idx_nodes(tab%dim2, tab%var2_nodes, val, ix, t, h)
184 end if
185 end subroutine locate_idx_axis2
186
187 !> 1D cubic Hermite basis on t in [0, 1] (value weights).
188 !> H0 = 2t^3 - 3t^2 + 1 value at t=0 H2 = -2t^3 + 3t^2 value at t=1
189 !> H1 = t^3 - 2t^2 + t slope at t=0 H3 = t^3 - t^2 slope at t=1
190 pure subroutine cubic_basis(t, H0, H1, H2, H3)
191 double precision, intent(in) :: t
192 double precision, intent(out) :: h0, h1, h2, h3
193 double precision :: t2, t3
194 t2 = t * t
195 t3 = t2 * t
196 h0 = 2.0d0*t3 - 3.0d0*t2 + 1.0d0
197 h1 = t3 - 2.0d0*t2 + t
198 h2 = -2.0d0*t3 + 3.0d0*t2
199 h3 = t3 - t2
200 end subroutine cubic_basis
201
202 !> Bicubic Hermite evaluator: value only.
203 !
204 !> 4 stored derivatives per corner (f, fx, fy, fxy) x 4 corners = 16
205 !> conditions; fully determines the 16-coefficient degree-(3,3)
206 !> polynomial. The stored fx, fy, fxy are physical-axis derivatives;
207 !> we multiply by the local cell widths to convert to unit-interval
208 !> basis coordinates.
209 pure subroutine bicubic_hermite_eval(f_t, fx_t, fy_t, fxy_t, x, y, val)
210 type(eos_table_container), intent(in) :: f_t, fx_t, fy_t, fxy_t
211 double precision, intent(in) :: x, y
212 double precision, intent(out) :: val
213 integer :: ix, iy
214 double precision :: tx, ty, dx, dy
215 double precision :: h0x, h1x, h2x, h3x
216 double precision :: h0y, h1y, h2y, h3y
217 double precision :: f00, f10, f01, f11
218 double precision :: fx00, fx10, fx01, fx11
219 double precision :: fy00, fy10, fy01, fy11
220 double precision :: fxy00, fxy10, fxy01, fxy11
221
222 call locate_idx_axis1(f_t, x, ix, tx, dx)
223 call locate_idx_axis2(f_t, y, iy, ty, dy)
224
225 call cubic_basis(tx, h0x, h1x, h2x, h3x)
226 call cubic_basis(ty, h0y, h1y, h2y, h3y)
227
228 f00 = f_t%table(ix, iy ); f10 = f_t%table(ix+1, iy )
229 f01 = f_t%table(ix, iy+1); f11 = f_t%table(ix+1, iy+1)
230 fx00 = fx_t%table(ix, iy ) * dx
231 fx10 = fx_t%table(ix+1, iy ) * dx
232 fx01 = fx_t%table(ix, iy+1) * dx
233 fx11 = fx_t%table(ix+1, iy+1) * dx
234 fy00 = fy_t%table(ix, iy ) * dy
235 fy10 = fy_t%table(ix+1, iy ) * dy
236 fy01 = fy_t%table(ix, iy+1) * dy
237 fy11 = fy_t%table(ix+1, iy+1) * dy
238 fxy00 = fxy_t%table(ix, iy ) * dx * dy
239 fxy10 = fxy_t%table(ix+1, iy ) * dx * dy
240 fxy01 = fxy_t%table(ix, iy+1) * dx * dy
241 fxy11 = fxy_t%table(ix+1, iy+1) * dx * dy
242
243 val = h0x*h0y*f00 + h2x*h0y*f10 + h0x*h2y*f01 + h2x*h2y*f11 &
244 + h1x*h0y*fx00 + h3x*h0y*fx10 + h1x*h2y*fx01 + h3x*h2y*fx11 &
245 + h0x*h1y*fy00 + h2x*h1y*fy10 + h0x*h3y*fy01 + h2x*h3y*fy11 &
246 + h1x*h1y*fxy00 + h3x*h1y*fxy10 + h1x*h3y*fxy01 + h3x*h3y*fxy11
247 end subroutine bicubic_hermite_eval
248
249 !> Public wrappers -- code-unit out.
250 double precision function entropy_t_from_nh_eint(Tfwd, Tfwd_x, Tfwd_y, Tfwd_xy, &
251 log_nH_code, log_e_nh_code) &
252 result(t_code)
253 type(eos_table_container), intent(in) :: tfwd, tfwd_x, tfwd_y, tfwd_xy
254 double precision, intent(in) :: log_nh_code, log_e_nh_code
255 double precision :: t_cgs
256 call bicubic_hermite_eval(tfwd, tfwd_x, tfwd_y, tfwd_xy, &
257 log_nh_code, log_e_nh_code, t_cgs)
258 t_code = t_cgs / unit_temperature
259 end function entropy_t_from_nh_eint
260
261 pure double precision function entropy_p_nh_from_eint(pfwd, pfwd_x, pfwd_y, pfwd_xy, &
262 log_nH_code, log_e_nh_code) &
263 result(p_nh_code)
264 type(eos_table_container), intent(in) :: pfwd, pfwd_x, pfwd_y, pfwd_xy
265 double precision, intent(in) :: log_nh_code, log_e_nh_code
266 double precision :: p_cgs, nh_cgs
267 call bicubic_hermite_eval(pfwd, pfwd_x, pfwd_y, pfwd_xy, &
268 log_nh_code, log_e_nh_code, p_cgs)
269 nh_cgs = 10.0d0**(log_nh_code + dlog10(unit_numberdensity))
270 p_nh_code = (p_cgs / nh_cgs) * unit_numberdensity / unit_pressure
271 end function entropy_p_nh_from_eint
272
273 !> Forward: ne/nH from (log nH, log eint/nH). Single bicubic Hermite
274 !> eval of the neOnH table.
275 double precision function entropy_y_from_nh_eint(neOnH, neOnH_x, neOnH_y, &
276 neOnH_xy, log_nH_code, &
277 log_e_nh_code) result(y)
278 type(eos_table_container), intent(in) :: neonh, neonh_x, neonh_y, neonh_xy
279 double precision, intent(in) :: log_nh_code, log_e_nh_code
280 call bicubic_hermite_eval(neonh, neonh_x, neonh_y, neonh_xy, &
281 log_nh_code, log_e_nh_code, y)
282 end function entropy_y_from_nh_eint
283
284 !> Forward: T and y from (log nH, log eint/nH) -- combined for the
285 !> update_eos_LTE hot path that needs both at once.
286 subroutine entropy_t_and_y_from_nh_eint(Tfwd, Tfwd_x, Tfwd_y, Tfwd_xy, &
287 neOnH, neOnH_x, neOnH_y, neOnH_xy, &
288 log_nH_code, log_e_nh_code, &
289 T_code, y_out)
290 !> Fused (T, y) lookup: shares ONE cell-location call between the two
291 !> bicubic Hermite evaluations. Tfwd and neOnH live on the same
292 !> adaptive (lr, le) grid (same axis nodes), so the (ix, iy, tx, ty,
293 !> dx, dy) coordinates and the cubic-basis values are identical for
294 !> both. We compute them once and re-use, saving the locate work
295 !> (binary search on adaptive axes) and the basis evaluations.
296 type(eos_table_container), intent(in) :: tfwd, tfwd_x, tfwd_y, tfwd_xy
297 type(eos_table_container), intent(in) :: neonh, neonh_x, neonh_y, neonh_xy
298 double precision, intent(in) :: log_nh_code, log_e_nh_code
299 double precision, intent(out) :: t_code, y_out
300 double precision :: t_cgs
301 integer :: ix, iy
302 double precision :: tx, ty, dx, dy
303 double precision :: h0x, h1x, h2x, h3x
304 double precision :: h0y, h1y, h2y, h3y
305
306 call locate_idx_axis1(tfwd, log_nh_code, ix, tx, dx)
307 call locate_idx_axis2(tfwd, log_e_nh_code, iy, ty, dy)
308 call cubic_basis(tx, h0x, h1x, h2x, h3x)
309 call cubic_basis(ty, h0y, h1y, h2y, h3y)
310
311 t_cgs = contract_value(tfwd, tfwd_x, tfwd_y, tfwd_xy, ix, iy, &
312 dx, dy, h0x, h1x, h2x, h3x, h0y, h1y, h2y, h3y)
313 y_out = contract_value(neonh, neonh_x, neonh_y, neonh_xy, ix, iy, &
314 dx, dy, h0x, h1x, h2x, h3x, h0y, h1y, h2y, h3y)
315 t_code = t_cgs / unit_temperature
316 end subroutine entropy_t_and_y_from_nh_eint
317
318 !> Bicubic Hermite contraction given pre-computed cell coordinates and
319 !> basis values. Lets multiple quantities at the SAME query point share
320 !> the cell-location and basis-evaluation work. Returns value only.
321 pure double precision function contract_value(f_t, fx_t, fy_t, fxy_t, &
322 ix, iy, dx, dy, &
323 H0x, H1x, H2x, H3x, &
324 H0y, H1y, H2y, H3y) result(val)
325 !> Shared-locate bicubic-Hermite contraction for fused multi-quantity
326 !> lookups at the same query point.
327 type(eos_table_container), intent(in) :: f_t, fx_t, fy_t, fxy_t
328 integer, intent(in) :: ix, iy
329 double precision, intent(in) :: dx, dy
330 double precision, intent(in) :: h0x, h1x, h2x, h3x
331 double precision, intent(in) :: h0y, h1y, h2y, h3y
332 double precision :: f00, f10, f01, f11
333 double precision :: fx00, fx10, fx01, fx11
334 double precision :: fy00, fy10, fy01, fy11
335 double precision :: fxy00, fxy10, fxy01, fxy11
336 f00 = f_t%table(ix, iy ); f10 = f_t%table(ix+1, iy )
337 f01 = f_t%table(ix, iy+1); f11 = f_t%table(ix+1, iy+1)
338 fx00 = fx_t%table(ix, iy ) * dx
339 fx10 = fx_t%table(ix+1, iy ) * dx
340 fx01 = fx_t%table(ix, iy+1) * dx
341 fx11 = fx_t%table(ix+1, iy+1) * dx
342 fy00 = fy_t%table(ix, iy ) * dy
343 fy10 = fy_t%table(ix+1, iy ) * dy
344 fy01 = fy_t%table(ix, iy+1) * dy
345 fy11 = fy_t%table(ix+1, iy+1) * dy
346 fxy00 = fxy_t%table(ix, iy ) * dx * dy
347 fxy10 = fxy_t%table(ix+1, iy ) * dx * dy
348 fxy01 = fxy_t%table(ix, iy+1) * dx * dy
349 fxy11 = fxy_t%table(ix+1, iy+1) * dx * dy
350 val = h0x*h0y*f00 + h2x*h0y*f10 + h0x*h2y*f01 + h2x*h2y*f11 &
351 + h1x*h0y*fx00 + h3x*h0y*fx10 + h1x*h2y*fx01 + h3x*h2y*fx11 &
352 + h0x*h1y*fy00 + h2x*h1y*fy10 + h0x*h3y*fy01 + h2x*h3y*fy11 &
353 + h1x*h1y*fxy00 + h3x*h1y*fxy10 + h1x*h3y*fxy01 + h3x*h3y*fxy11
354 end function contract_value
355
356 !> Inverse: log10(eint/nH) from (log nH, log p/nH). Single bicubic
357 !> Hermite eval of the eintP table. Replaces p2eint bisection.
358 !
359 !> Returns the eint/p ratio for drop-in compatibility with the
360 !> existing p2eint_from_nH_p call sites which use it as
361 !> eint = p * (returned ratio).
362 double precision function entropy_eint_from_nh_p(eintP, eintP_x, eintP_y, eintP_xy, &
363 log_nH_code, log_p_nH_code) result(ratio)
364 !> Returns eint/p in dimensionless code units. The stored table value is
365 !> log10(eint/nH) in CGS; we convert to code (axis-2 shift = the same
366 !> log10(unit_pressure/unit_numberdensity) as for log(p/nH) and log(eint/nH))
367 !> before forming the ratio with log_p_nH_code, otherwise the units mix.
368 type(eos_table_container), intent(in) :: eintp, eintp_x, eintp_y, eintp_xy
369 double precision, intent(in) :: log_nh_code, log_p_nh_code
370 double precision :: log_e_nh_cgs, log_e_nh_code
371 call bicubic_hermite_eval(eintp, eintp_x, eintp_y, eintp_xy, &
372 log_nh_code, log_p_nh_code, log_e_nh_cgs)
373 log_e_nh_code = log_e_nh_cgs - dlog10(unit_pressure / unit_numberdensity)
374 ratio = 10.0d0**(log_e_nh_code - log_p_nh_code)
375 end function entropy_eint_from_nh_p
376
377 !> Inverse: Gamma_1 from (log nH, log p/nH). Bicubic Hermite of g1p.
378 double precision function entropy_gamma1_from_nh_p(g1p, g1p_x, g1p_y, g1p_xy, &
379 log_nH_code, log_p_nH_code) &
380 result(g1)
381 type(eos_table_container), intent(in) :: g1p, g1p_x, g1p_y, g1p_xy
382 double precision, intent(in) :: log_nh_code, log_p_nh_code
383 call bicubic_hermite_eval(g1p, g1p_x, g1p_y, g1p_xy, &
384 log_nh_code, log_p_nh_code, g1)
385 end function entropy_gamma1_from_nh_p
386
387 !> Inverse: log10(eint/nH) from (log nH, log T). Single bicubic
388 !> Hermite eval of the eintT table.
389 double precision function entropy_eint_from_nh_t(eintT, eintT_x, eintT_y, eintT_xy, &
390 log_nH_code, log_T_code) &
391 result(log_e_nh_code)
392 !> Stored table value is log10(eint/nH) in CGS; convert to code units
393 !> before returning so the caller can use it as a code-unit log directly.
394 type(eos_table_container), intent(in) :: eintt, eintt_x, eintt_y, eintt_xy
395 double precision, intent(in) :: log_nh_code, log_t_code
396 double precision :: log_e_nh_cgs
397 call bicubic_hermite_eval(eintt, eintt_x, eintt_y, eintt_xy, &
398 log_nh_code, log_t_code, log_e_nh_cgs)
399 log_e_nh_code = log_e_nh_cgs - dlog10(unit_pressure / unit_numberdensity)
400 end function entropy_eint_from_nh_t
401
402
403 !> Per-container code-unit shift + prepare for loaded entropy tables
404 !> (moved from mod_eos_LTE_tables; uses the shared infra there).
405 subroutine entropy_table_prepare(tc)
406 !> Bundle ensure_axis_nodes + precompute_step_inv + build_guards + validate,
407 !> the identical four-step setup each loaded entropy table container needs.
408 type(eos_table_container), intent(inout) :: tc
409 call ensure_axis_nodes(tc)
410 call precompute_step_inv(tc)
411 call eos_build_guards(tc)
412 call eos_validate_table(tc, trim(tc%filename))
413 end subroutine entropy_table_prepare
414
415
416 subroutine entropy_shift_prepare(tc, axis2_is_T)
417 type(eos_table_container), intent(inout) :: tc
418 logical, intent(in) :: axis2_is_t
419 if (axis2_is_t) then
420 call shift_axis_to_code_t(tc)
421 else
422 call shift_axis_to_code(tc)
423 end if
424 call entropy_table_prepare(tc)
425 end subroutine entropy_shift_prepare
426
427end module mod_eos_lte_entropy
428!> Needs a line after to pass the preprocessor
subroutine, public mpistop(message)
Exit MPI-AMRVAC with an error message.
EoS state container – the single thermodynamic authority for AMRVAC.
type(eos_container), allocatable, public eos
The single EoS state object, allocated in eos_init and shared (read-mostly) across all EoS sub-module...
Interpolation kernels for the EoS tables (pure math; no EoS state).
subroutine, public precompute_step_inv(tc)
Entropy-method LTE EoS: every query is ONE bicubic Hermite evaluation.
double precision function, public entropy_eint_from_nh_t(eintt, eintt_x, eintt_y, eintt_xy, log_nh_code, log_t_code)
Inverse: log10(eint/nH) from (log nH, log T). Single bicubic Hermite eval of the eintT table.
pure double precision function, public entropy_p_nh_from_eint(pfwd, pfwd_x, pfwd_y, pfwd_xy, log_nh_code, log_e_nh_code)
double precision function, public entropy_t_from_nh_eint(tfwd, tfwd_x, tfwd_y, tfwd_xy, log_nh_code, log_e_nh_code)
Public wrappers – code-unit out.
subroutine, public finalise_entropy_lte()
Entropy-method finalise: shift each loaded table's axes from CGS to code units and run the standard p...
double precision function, public entropy_gamma1_from_nh_p(g1p, g1p_x, g1p_y, g1p_xy, log_nh_code, log_p_nh_code)
Inverse: Gamma_1 from (log nH, log p/nH). Bicubic Hermite of g1p.
subroutine, public entropy_t_and_y_from_nh_eint(tfwd, tfwd_x, tfwd_y, tfwd_xy, neonh, neonh_x, neonh_y, neonh_xy, log_nh_code, log_e_nh_code, t_code, y_out)
Forward: T and y from (log nH, log eint/nH) – combined for the update_eos_LTE hot path that needs bot...
double precision function, public entropy_y_from_nh_eint(neonh, neonh_x, neonh_y, neonh_xy, log_nh_code, log_e_nh_code)
Forward: ne/nH from (log nH, log eint/nH). Single bicubic Hermite eval of the neOnH table.
double precision function, public entropy_eint_from_nh_p(eintp, eintp_x, eintp_y, eintp_xy, log_nh_code, log_p_nh_code)
Inverse: log10(eint/nH) from (log nH, log p/nH). Single bicubic Hermite eval of the eintP table....
subroutine, public load_entropy_lte()
Forward (log nH, log eint/nH) -> thermodynamic state.
Shared LTE lookup-table infrastructure (build/IO; not on the hot path).
subroutine, public eos_validate_table(tc, name)
Defensive consistency check for one table after init. Aborts with a diagnostic message if any silent-...
subroutine, public load_tables_lte(fieldname)
Read one named table file into its eos% container. The filename encodes the composition (H or HHe) an...
subroutine, public shift_axis_to_code(tc)
Shift a table's (log_nH, log_eint/nH) axes – and adaptive node arrays if present – from CGS storage t...
subroutine, public shift_axis_to_code_t(tc)
subroutine, public ensure_axis_nodes(tc)
Ensure tcvar1_nodes / tcvar2_nodes are allocated and populated so that build_*_table routines and oth...
subroutine, public eos_build_guards(tc)
Build guard (bucket) arrays so that adaptive index lookup is O(1). No-op for uniform tables....
subroutine, public precompute_fi_bypass_constants()
This module contains definitions of global parameters and variables and some generic functions/subrou...
double precision unit_numberdensity
Physical scaling factor for number density.
double precision unit_pressure
Physical scaling factor for pressure.
integer mype
The rank of the current MPI task.
double precision unit_temperature
Physical scaling factor for temperature.
double precision, dimension(:,:), allocatable dx
spatial steps for all dimensions at all levels