47 character(len=std_len) :: AMRVAC_DIR
70 procedure(convert_condition),
pointer :: to_primitive_impl => null(), &
71 to_conserved_impl => null()
72 procedure(update_eos_spaces),
pointer :: update_eos_impl => null()
73 procedure(get_eos_variable_alt),
pointer :: pthermal_impl => null(), csound2_impl => null(), &
74 tfromei_impl => null()
81 subroutine eos_read_params(files)
82 character(len=*),
intent(in) :: files(:)
89 character(len=std_len) :: eos_type, table_location
90 character(len=20) :: eos_method, gamma1_method, p2eint_method, pi_table
91 double precision :: He_abundance, gamma
94 namelist /eos_list/ eos_type, table_location, ione, he_abundance, gamma, &
95 eos_method, gamma1_method, p2eint_method, pi_table
100 pi_table =
'chromosphere'
101 gamma1_method =
'exact'
102 p2eint_method =
'table'
106 call get_environment_variable(
"AMRVAC_DIR", amrvac_dir)
107 table_location = trim(amrvac_dir)//
"/src/tables/eos_tables/uniform256/"
110 do n = 1,
size(files)
111 open(
unitpar, file=trim(files(n)), status=
"old")
112 read(
unitpar, eos_list,
end=111)
117 eos%eos_type = eos_type
118 eos%method = eos_method
119 eos%pi_table = pi_table
120 eos%gamma1_method = gamma1_method
121 eos%p2eint_method = p2eint_method
122 eos%table_location = table_location
123 eos%He_abundance = he_abundance
128 eos%gamma_minus_1 =
eos%gamma - 1.0d0
129 eos%inv_gamma = 1.0d0 /
eos%gamma
130 if (abs(
eos%gamma_minus_1) > 1.0
d-12)
then
131 eos%inv_gamma_minus_1 = 1.0d0 /
eos%gamma_minus_1
133 eos%inv_gamma_minus_1 = 0.0d0
135 eos%nH2rhoFactor = 1.0d0
136 select case (
eos%method)
141 select case (
eos%eos_type)
149 write(*,*)
"EoS type: "//trim(
eos%eos_type)
150 if (
eos%eos_type ==
'LTE') &
151 write(*,*)
"EoS table location: "//trim(
eos%table_location)
155 call eos_validate_params()
157 end subroutine eos_read_params
163 subroutine eos_validate_params()
166 if (eos%eos_type ==
'FI' .and. eos%ionE)
then
168 if(mype==0)
write(*,*)
"WARNING: eos_type = 'FI' requires ionE = .false."
172 if (eos%eos_type ==
'PI')
then
173 select case (trim(eos%pi_table))
174 case (
'chromosphere',
'flare',
'prominence')
177 call mpistop(
"eos_type='PI': pi_table must be "// &
178 "'chromosphere', 'flare', or 'prominence'")
187 if (eos%ionE .and. trim(eos%pi_table) ==
'prominence')
then
188 call mpistop(
"eos_type='PI' with ionE=T requires a T-only table "// &
189 "(chromosphere or flare); prominence is no-energy only")
191 if(mype==0)
write(*,*)
"EoS PI table: "//trim(eos%pi_table)// &
197 if (eos%method /=
'analytic' .and. eos%method /=
'state' &
198 .and. eos%method /=
'tables' .and. eos%method_id /= eos_entropy)
then
199 call mpistop(
"Unknown eos_method: "//trim(eos%method)// &
200 " (expected 'state', 'analytic', or 'entropy')")
202 if (eos%eos_type ==
'FI' .and. eos%method_id == eos_analytic)
then
203 call mpistop(
"eos_method='analytic' requires eos_type='LTE'")
207 if (eos%gamma1_method /=
'exact' .and. eos%gamma1_method /=
'effective' &
208 .and. eos%gamma1_method /=
'constant')
then
209 call mpistop(
"Unknown gamma1_method: "//trim(eos%gamma1_method)// &
210 " (expected 'exact', 'effective', or 'constant')")
214 if (eos%method_id == eos_analytic)
then
215 if (eos%He_abundance > 0.0d0 .and. mype == 0)
write(*,*) &
216 "eos_method='analytic' keeps helium neutral, He_abundance=", eos%He_abundance
218 if (eos%gamma1_method ==
'effective')
then
219 if (mype == 0)
write(*,*) &
220 "WARNING: gamma1_method='effective' not applicable with analytic EoS."
221 if (mype == 0)
write(*,*) &
222 " Falling back to gamma1_method='exact' (analytic 2D table)."
223 eos%gamma1_method =
'exact'
225 if (.not. eos%ionE .and. mype == 0)
then
226 write(*,*)
"WARNING: eos_method='analytic' without ionE"
227 write(*,*)
" reduces to ideal gas. Consider eos_type='FI'."
232 if (eos%eos_type ==
'LTE' .and. eos%ionE .and. &
233 eos%gamma1_method ==
'effective')
then
234 if (mype == 0)
write(*,*) &
235 "NOTE: gamma1_method='effective' builds gamma_eff = 1+p/eint table."
238 end subroutine eos_validate_params
245 call eos_read_params(par_files)
248 eos%get_rho => get_rho
250 eos%get_ne_nH => get_ne_nh
255 select case (eos%eos_type)
256 case (
'FI');
call eos_init_fi()
257 case (
'LTE');
call eos_init_lte()
258 case (
'PI');
call eos_init_pi()
260 call mpistop(
'eos_init: eos_type '//trim(eos%eos_type)//
' not recognised')
274 if (.not.
allocated(eos)) &
275 call mpistop(
'eos_finalise: eos not allocated')
279 eos%p2eint_bisect = (eos%p2eint_method ==
'bisect')
281 select case (eos%eos_type)
283 call eos_finalise_lte()
285 call eos_finalise_fi()
287 call eos_finalise_pi()
289 call mpistop(
'eos_finalise: eos_type '//trim(eos%eos_type)//
' not recognised')
292 eos%get_temperature_from_etot => get_temperature_from_etot
295 if (eos%type_id == eos_type_lte)
then
296 if (eos%method_id == eos_analytic)
then
297 eos%eint_nH_min = eos%inv_gamma_minus_1 * 100.0d0 / unit_temperature
299 eos%eint_nH_min = 10.0d0**eos%T%var2_min
302 call eos_time_dispatch()
308 subroutine eos_time_dispatch()
311 if (
associated(eos%to_primitive))
then
312 to_primitive_impl => eos%to_primitive
313 eos%to_primitive => timed_to_primitive
317 if (
associated(eos%to_conserved))
then
318 to_conserved_impl => eos%to_conserved
319 eos%to_conserved => timed_to_conserved
323 if (
associated(eos%get_thermal_pressure))
then
324 pthermal_impl => eos%get_thermal_pressure
325 eos%get_thermal_pressure => timed_pthermal
328 if (
associated(eos%update_eos))
then
329 update_eos_impl => eos%update_eos
330 eos%update_eos => timed_update_eos
332 if (
associated(eos%get_csound2))
then
333 csound2_impl => eos%get_csound2
334 eos%get_csound2 => timed_csound2
336 if (
associated(eos%get_temperature_from_eint))
then
337 tfromei_impl => eos%get_temperature_from_eint
338 eos%get_temperature_from_eint => timed_tfromei
340 end subroutine eos_time_dispatch
343 subroutine timed_to_primitive(ixI^L, ixO^L, w, x)
345 integer,
intent(in) :: ixi^l, ixo^l
346 double precision,
intent(inout) :: w(ixi^s,
nw)
347 double precision,
intent(in) :: x(ixi^s, 1:ndim)
348 call eos_timer_start()
349 call to_primitive_impl(ixi^l, ixo^l, w, x)
350 call eos_timer_stop(timeeos_conv)
351 end subroutine timed_to_primitive
353 subroutine timed_to_conserved(ixI^L, ixO^L, w, x)
355 integer,
intent(in) :: ixi^l, ixo^l
356 double precision,
intent(inout) :: w(ixi^s,
nw)
357 double precision,
intent(in) :: x(ixi^s, 1:ndim)
358 call eos_timer_start()
359 call to_conserved_impl(ixi^l, ixo^l, w, x)
360 call eos_timer_stop(timeeos_conv)
361 end subroutine timed_to_conserved
363 subroutine timed_update_eos(ixI^L, ixO^L, w, x)
365 integer,
intent(in) :: ixi^l, ixo^l
366 double precision,
intent(inout) :: w(ixi^s,
nw)
367 double precision,
intent(in) :: x(ixi^s, 1:ndim)
368 call eos_timer_start()
369 call update_eos_impl(ixi^l, ixo^l, w, x)
370 call eos_timer_stop(timeeos_update)
371 end subroutine timed_update_eos
373 subroutine timed_pthermal(w, x, ixI^L, ixO^L, res)
375 integer,
intent(in) :: ixi^l, ixo^l
376 double precision,
intent(in) :: w(ixi^s,
nw), x(ixi^s, 1:ndim)
377 double precision,
intent(out) :: res(ixi^s)
378 call eos_timer_start()
379 call pthermal_impl(w, x, ixi^l, ixo^l, res)
380 call eos_timer_stop(timeeos_pthermal)
381 end subroutine timed_pthermal
383 subroutine timed_csound2(w, x, ixI^L, ixO^L, res)
385 integer,
intent(in) :: ixi^l, ixo^l
386 double precision,
intent(in) :: w(ixi^s,
nw), x(ixi^s, 1:ndim)
387 double precision,
intent(out) :: res(ixi^s)
388 call eos_timer_start()
389 call csound2_impl(w, x, ixi^l, ixo^l, res)
390 call eos_timer_stop(timeeos_csound)
391 end subroutine timed_csound2
393 subroutine timed_tfromei(w, x, ixI^L, ixO^L, res)
395 integer,
intent(in) :: ixi^l, ixo^l
396 double precision,
intent(in) :: w(ixi^s,
nw), x(ixi^s, 1:ndim)
397 double precision,
intent(out) :: res(ixi^s)
398 call eos_timer_start()
399 call tfromei_impl(w, x, ixi^l, ixo^l, res)
400 call eos_timer_stop(timeeos_tfromei)
401 end subroutine timed_tfromei
405 type(state),
intent(inout) :: psx(:)
406 integer :: iigrid, igrid
410 do iigrid=1,igridstail_active; igrid=igrids_active(iigrid);
411 call eos%update_eos(ixg^ll,ixg^ll,psx(igrid)%w,psx(igrid)%x)
422 logical,
intent(in) :: sat_r_variable
423 fl%get_temperature_from_conserved => eos%get_temperature_from_etot
424 if (eos%eos_type ==
'LTE' .and. eos%ionE)
then
426 fl%get_temperature_ciso2_from_eint => get_temperature_from_eint_fast_lte
428 fl%get_temperature_from_eint => eos%get_temperature_from_eint
429 fl%sat_R_variable = sat_r_variable
431 fl%get_rho => eos%get_rho
432 fl%get_ne_nH => eos%get_ne_nH
433 fl%get_var_Rfactor => eos%get_Rfactor
434 fl%inv_gamma_minus_1 = eos%inv_gamma_minus_1
435 fl%nH2rhoFactor = eos%nH2rhoFactor
436 fl%log_T_floor = eos_get_log_t_floor()
437 fl%eint_from_T => eint_nh_from_t
subroutine, public mpistop(message)
Exit MPI-AMRVAC with an error message.
EoS state container – the single thermodynamic authority for AMRVAC.
integer, parameter, public eos_analytic
integer, parameter, public eos_type_pi
integer, parameter, public eos_type_fi
EoS-type selector, decoded once from eoseos_type into eostype_id. Used by the mode-specific kernels t...
integer, parameter, public eos_state
slot interfaces, for routines that hold or wrap an EoS slot
integer, parameter, public eos_entropy
type(eos_container), allocatable, public eos
The single EoS state object, allocated in eos_init and shared (read-mostly) across all EoS sub-module...
integer, parameter, public eos_type_lte
integer, public iw_log_nh
wextra index for the cached log10(nH) used during STS substeps (-1 = not allocated)....
FI (fully-ionised, constant-gamma) EoS kernels for the eos% family.
subroutine, public get_gamma1_fi(w, x, ixil, ixol, gamma1)
Gamma_1 for the fully-ionised ideal gas: constant eosgamma.
Interpolation kernels for the EoS tables (pure math; no EoS state).
Analytic hydrogen Saha EoS with neutral helium (eos_method == 'analytic').
Shared LTE lookup-table infrastructure (build/IO; not on the hot path).
LTE (Saha-table) EoS kernels and finalise for the eos% family.
PI (partial-ionisation, eos_type='PI') arm of the eos% family.
subroutine, public eos_finalise_pi()
PI arm of eos_finalise (after unit_* are set): ride FI's ideal-gas getter set and RR=1 normalisation ...
subroutine, public eos_init_pi()
Lifecycle (PI arms of the eos_init / eos_finalise dispatchers). The eos% block getters (update_eos_PI...
Shared EoS accessors (EoS-type-agnostic) for the eos% family.
subroutine, public get_ne_nh(ixil, ixol, w, x, ne, nh)
Return electron and hydrogen number densities in code units. For LTE (iw_ne allocated): ne from Saha ...
double precision function, public eos_get_log_t_floor()
Lower log10(T) bound for the (rho,T) inverse table; FI (no tables) floors at log10(smalldouble)....
Equation of state for AMRVAC, handled through a single eos_container object.
subroutine, public eos_init()
Phase 'create' (before units are known): allocate the EoS object, read its &eos_list parameters,...
subroutine, public prepare_eos_w_fields(psx)
subroutine, public eos_bind_tc(fl, sat_r_variable)
The EoS hooks of the conduction fluid fl. sat_R_variable is false when R is the constant 1,...
subroutine, public eos_finalise()
Phase 'commit' (after units are known): finalise the dispatch for the loaded physics – wire the metho...
This module contains definitions of global parameters and variables and some generic functions/subrou...
integer, parameter unitpar
file handle for IO
integer mype
The rank of the current MPI task.
double precision, dimension(:), allocatable, parameter d
This module defines the procedures of a physics module. It contains function pointers for the various...
procedure(sub_convert), pointer phys_to_primitive
procedure(sub_get_pthermal), pointer phys_get_pthermal
procedure(sub_convert), pointer phys_to_conserved
Thermal conduction for HD and MHD or RHD and RMHD or twofl (plasma-neutral) module Adaptation of mod_...
subroutine eos_timer_start()
Open an EoS timing window; inside an OpenMP parallel region the EoS is not timed.
double precision timeeos_update
double precision timeeos_pthermal
double precision timeeos_conv
subroutine eos_timer_stop(acc)
Close an EoS timing window, adding its time to acc when it is the outermost.
double precision timeeos_csound
double precision timeeos_tfromei
integer nw
Total number of variables.